

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Tutorial: crea un'API REST per calcolatrice con due integrazioni AWS di servizi e un'integrazione non proxy Lambda
<a name="integrating-api-with-aws-services-lambda"></a>

[Tutorial: creazione di una REST API con un'integrazione non proxy Lambda](getting-started-lambda-non-proxy-integration.md) utilizza esclusivamente l'integrazione `Lambda Function`. L'integrazione `Lambda Function` è un caso speciale del tipo di integrazione `AWS Service` in cui gran parte delle operazioni di configurazione dell'integrazione vengono eseguite automaticamente, ad esempio l'aggiunta automatica delle autorizzazioni basate su risorse necessarie per invocare la funzione Lambda. In questo caso, due integrazioni su tre utilizzano l'integrazione `AWS Service`. Questo tipo di integrazione offre un controllo maggiore, ma richiede l'esecuzione manuale di attività come la creazione e la definizione di un ruolo IAM contenente le autorizzazioni appropriate.



In questo tutorial verrà creata una funzione Lambda `Calc` che implementa operazioni aritmetiche di base, accettando e restituendo input e output in formato JSON. Verrà quindi creata un'API REST, che verrà integrata con la funzione Lambda nei modi seguenti:

1. Esponendo un metodo `GET` nella risorsa `/calc` per richiamare la funzione Lambda, fornendo l'input sotto forma di parametri delle stringhe di query (integrazione `AWS Service`).

1. Esponendo un metodo `POST` nella risorsa `/calc` per richiamare la funzione Lambda, fornendo l'input nel payload della richiesta del metodo (integrazione `AWS Service`).

1. Esponendo un metodo `GET` nelle risorse `/calc/{operand1}/{operand2}/{operator}` nidificate per richiamare la funzione Lambda, fornendo l'input sotto forma di parametri di percorso (integrazione `Lambda Function`).

Oltre a provare questo tutorial, puoi esaminare il [file di definizione OpenAPI](api-as-lambda-proxy-export-swagger-with-extensions.md) per l'API `Calc`, che è possibile importare in API Gateway seguendo le istruzioni in [Sviluppa REST APIs utilizzando OpenAPI in API Gateway](api-gateway-import-api.md).

**Topics**
+ [Creazione di un ruolo IAM prevedibile](#api-as-lambda-proxy-setup-iam-role-policies)
+ [Creazione di una funzione Lambda `Calc`](#api-as-lambda-proxy-create-lambda-function)
+ [Test della funzione Lambda `Calc`](#api-as-lambda-proxy-test-lambda-function-)
+ [Creazione di un'API `Calc`](#api-as-lambda-proxy-create-api-resources)
+ [Integrazione 1: creazione di un metodo `GET` con parametri di query per chiamare la funzione Lambda](#api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function)
+ [Integrazione 2: creazione di un metodo `POST` con un payload JSON per chiamare la funzione Lambda](#api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function)
+ [Integrazione 3: creazione di un metodo `GET` con parametri di percorso per chiamare la funzione Lambda](#api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function)
+ [Definizioni OpenAPI di un'API di esempio integrata con una funzione Lambda](api-as-lambda-proxy-export-swagger-with-extensions.md)

## Creazione di un ruolo IAM prevedibile
<a name="api-as-lambda-proxy-setup-iam-role-policies"></a>

Affinché l'API possa richiamare la funzione Lambda `Calc`, è necessario un ruolo IAM API Gateway prevedibile, ovvero un ruolo IAM con la relazione di trust seguente:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

Il ruolo che crei dovrà avere l'autorizzazione Lambda [InvokeFunction](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html). In caso contrario, il chiamante dell'API riceverà una risposta `500 Internal Server Error`. Per assegnare al ruolo questa autorizzazione, è necessario collegare al ruolo la policy IAM seguente:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "*"
        }
    ]
}
```

------

Ecco come procedere:

**Creazione di un ruolo IAM API Gateway prevedibile**

1. Accedi alla console IAM.

1. Scegliere **Roles (Ruoli)**.

1. Seleziona **Create Role (Crea ruolo)**.

1. In **Select type of trusted entity (Seleziona tipo di entità attendibile)**, scegli **AWS Service**.

1. In **Choose the service that will use this role (Scegli il servizio che utilizzerà questo ruolo)**, seleziona **Lambda**.

1. Scegli **Next: Permissions (Successivo: Autorizzazioni)**.

1. Selezionare **Create Policy (Crea policy)**.

   Si aprirà una nuova finestra **Create Policy** (Crea policy) della console. Nella finestra procedi nel seguente modo:

   1. Nella scheda **JSON**, sostituisci la policy esistente con la seguente:

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "lambda:InvokeFunction",
                  "Resource": "*"
              }
          ]
      }
      ```

------

   1. Scegliere **Review policy (Esamina policy)**.

   1. In**Review Policy** (Rivedi policy), effettua le operazioni seguenti:

      1. In **Name** (Nome), digita un nome, ad esempio **lambda\$1execute**.

      1. Selezionare **Create Policy (Crea policy)**.

1. Nella finestra **Create Role** (Crea ruolo) originaria della console, procedi nel seguente modo:

   1. In **Attach permissions policies** (Collega policy delle autorizzazioni), scegli la tua policy **lambda\$1execute** dall'elenco a discesa.

      Se la policy non è visualizzata nell'elenco, scegliere il pulsante di aggiornamento in alto. Non aggiornare la pagina del browser.

   1. Scegliere **Next: Tags (Successivo: Tag)**.

   1. Scegli **Next:Review** (Successivo:Rivedi).

   1. Per **Role name** (Nome ruolo), digita un nome, ad esempio **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

   1. Seleziona **Create role** (Crea ruolo).

1. Seleziona il tuo **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** nell'elenco dei ruoli.

1. Seleziona la scheda **Trust relationships** (Relazioni di trust).

1. Seleziona **Edit trust relationship (Modifica relazione di trust)**.

1. Sostituisci la policy esistente con la seguente:

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": {
           "Service": [
             "lambda.amazonaws.com",
             "apigateway.amazonaws.com"
           ]
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. Selezionare **Update Trust Policy (Aggiorna policy di trust)**.

1. Prendi nota dell'ARN per il ruolo appena creato. Sarà necessario in seguito.

## Creazione di una funzione Lambda `Calc`
<a name="api-as-lambda-proxy-create-lambda-function"></a>

Verrà quindi creata una funzione Lambda utilizzando la console Lambda.

1. Nella console Lambda, scegliere **Create function (Crea funzione)**.

1. Scegli **Author from Scratch** (Crea da zero).

1. In **Name (Nome)**, immettere **Calc**.

1. Per **Runtime**, scegli l'ultimo runtime supportato di **Node.js** o di **Python**.

1. Utilizza le impostazioni predefinite per tutte le altre opzioni.

1. Scegli **Crea funzione**.

1.  Copia la seguente funzione Lambda e incollala nel runtime preferito e nell'editor di codice nella console Lambda. 

------
#### [ Node.js ]

   ```
   export const handler = async function (event, context) {
     console.log("Received event:", JSON.stringify(event));
   
     if (
       event.a === undefined ||
       event.b === undefined ||
       event.op === undefined
     ) {
       return "400 Invalid Input";
     }
   
     const res = {};
     res.a = Number(event.a);
     res.b = Number(event.b);
     res.op = event.op;
     if (isNaN(event.a) || isNaN(event.b)) {
       return "400 Invalid Operand";
     }
     switch (event.op) {
       case "+":
       case "add":
         res.c = res.a + res.b;
         break;
       case "-":
       case "sub":
         res.c = res.a - res.b;
         break;
       case "*":
       case "mul":
         res.c = res.a * res.b;
         break;
       case "/":
       case "div":
         if (res.b == 0) {
           return "400 Divide by Zero";
         } else {
           res.c = res.a / res.b;
         }
         break;
       default:
         return "400 Invalid Operator";
     }
   
     return res;
   };
   ```

------
#### [ Python ]

   ```
   import json
   
   
   def lambda_handler(event, context):
       print(event)
   
       try:
           (event['a']) and (event['b']) and (event['op'])
       except KeyError:
           return '400 Invalid Input'
   
       try:
           res = {
               "a": float(
                   event['a']), "b": float(
                   event['b']), "op": event['op']}
       except ValueError:
           return '400 Invalid Operand'
   
       if event['op'] == '+':
           res['c'] = res['a'] + res['b']
       elif event['op'] == '-':
           res['c'] = res['a'] - res['b']
       elif event['op'] == '*':
           res['c'] = res['a'] * res['b']
       elif event['op'] == '/':
           if res['b'] == 0:
               return '400 Divide by Zero'
           else:
               res['c'] = res['a'] / res['b']
       else:
           return '400 Invalid Operator'
   
       return res
   ```

------

1. In Execution role (Ruolo di esecuzione) scegliere **Choose an existing role (Scegli un ruolo esistente)**.

1. Immettere l'ARN per il ruolo **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** creato in precedenza.

1. Selezionare **Deploy (Distribuisci)**.

 Questa funzione richiede due operandi (`a` e `b`) e un operatore (`op`) del parametro di input `event`. L'input è un oggetto JSON con il formato seguente: 

```
{
  "a": "Number" | "String",
  "b": "Number" | "String",
  "op": "String"
}
```

Questa funzione restituisce il risultato calcolato (`c`) e l'input. Per un input non valido, la funzione restituisce il valore null o la stringa "Invalid op" come risultato. L'output ha il formato JSON seguente: 

```
{
  "a": "Number",
  "b": "Number",
  "op": "String",
  "c": "Number" | "String"
}
```

Prima dell'integrazione con l'API nella fase successiva, è necessario testare la funzione nella console Lambda. 

## Test della funzione Lambda `Calc`
<a name="api-as-lambda-proxy-test-lambda-function-"></a>

Di seguito viene descritto come testare la funzione `Calc` nella console Lambda:

1. Seleziona la scheda **Test**.

1. Come nome dell'evento di test, immettere **calc2plus5**.

1. Sostituire la definizione dell'evento di test con quanto segue:

   ```
   {
     "a": "2",
     "b": "5",
     "op": "+"
   }
   ```

1. Scegli **Save (Salva)**.

1. Scegli **Test (Esegui test)**.

1. Espandere **Execution result: succeeded (Risultato esecuzione: riuscita)**. Verrà visualizzato un codice analogo al seguente:

   ```
   {
     "a": 2,
     "b": 5,
     "op": "+",
     "c": 7
   }
   ```

## Creazione di un'API `Calc`
<a name="api-as-lambda-proxy-create-api-resources"></a>

Nella procedura seguente viene illustrato come creare un'API per la funzione Lambda `Calc` appena creata. Nelle sezioni successive verranno aggiunti metodi e risorse.

**Come creare un’API**

1. Accedi alla console API Gateway all'indirizzo [https://console.aws.amazon.com/apigateway.](https://console.aws.amazon.com/apigateway)

1. Se si utilizza API Gateway per la prima volta, verrà visualizzata una pagina che presenta le caratteristiche del servizio. In **API REST**, scegliere **Crea**. Quando appare il popup **Create Example API (Crea API di esempio)**, scegliere **OK**.

   Se non è la prima volta che si utilizza API Gateway, scegliere **Create API (Crea API)**. In **API REST**, scegliere **Crea**.

1.  Per **API name (Nome API)**, immettere **LambdaCalc**.

1. (Facoltativo) In **Descrizione**, immetti una descrizione.

1. Lasciare l'opzione **Tipo di endpoint API** impostata su **Regionale**.

1. Per il tipo di **indirizzo IP**, selezionare. **IPv4**

1. Seleziona **Create API** (Crea API).

## Integrazione 1: creazione di un metodo `GET` con parametri di query per chiamare la funzione Lambda
<a name="api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function"></a>

Creando un metodo `GET` che passa i parametri delle stringhe di query alla funzione Lambda, si permette all'API di essere richiamata da un browser. Questo approccio può essere utile, soprattutto APIs perché consente l'accesso aperto.

Dopo l'API, è necessario creare una risorsa. In genere, le risorse API sono organizzate in una struttura di risorse in base alla logica dell'applicazione. In questa fase crei una risorsa **/calc**. 

**Per creare una risorsa **/calc****

1. Scegli **Crea risorsa**.

1. Mantieni l'opzione **Risorsa proxy** disattivata. 

1. Mantieni **Percorso risorsa** impostato su `/`.

1. Per **Resource Name (Nome risorsa)** immetti **calc**.

1. Mantieni **CORS (Cross Origin Resource Sharing)** disattivato.

1. Scegli **Crea risorsa**.

Creando un metodo `GET` che passa i parametri delle stringhe di query alla funzione Lambda, si permette all'API di essere richiamata da un browser. Questo approccio può essere utile, soprattutto APIs perché consente l'accesso aperto.

Con questo metodo, Lambda richiede che venga usata la richiesta `POST` per richiamare qualsiasi funzione Lambda. Questo esempio mostra che il metodo HTTP in una richiesta del metodo di front-end può essere diverso dalla richiesta di integrazione nel back-end.

**Creazione di un metodo `GET`**

1. Seleziona la risorsa **/calc** quindi scegli **Crea metodo**.

1. Per **Tipo di metodo** seleziona **GET**.

1. Per **Tipo di integrazione** seleziona **Servizio AWS**.

1. Per **Regione AWS**, seleziona il Regione AWS luogo in cui hai creato la tua funzione Lambda.

1. Per **Servizio AWS** seleziona **Lambda**.

1. Lascia vuoto **Sottodominio AWS **.

1. Per **Metodo HTTP** seleziona **POST**.

1. In **Tipo di operazione** scegli **Utilizza sostituzione percorso**. Questa opzione permette di specificare l'ARN dell'operazione [Invoke (Richiama)](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) per eseguire la funzione `Calc`. 

1. Per **Sostituzione percorso** immetti **2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**. Per** *account-id***, inserisci il tuo Account AWS ID. Per***us-east-2***, inserisci Regione AWS dove hai creato la tua funzione Lambda. 

1. Per **Ruolo di esecuzione** immetti l'ARN del ruolo per **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

1. Non modificare le impostazioni di **Cache delle credenziali** e **Timeout predefinito**.

1. Scegli **Impostazioni della richiesta del metodo**.

1. Per **Validatore richiesta** seleziona **Convalida parametri di stringa query e intestazioni**.

   Questa impostazione restituisce un messaggio di errore se il client non specifica i parametri obbligatori.

1. Scegli **Parametri della stringa di query URL**.

   A questo punto si configurano i parametri della stringa di query per il metodo **GET** sulla risorsa **/calc** in modo da poter ricevere l'input per conto della funzione Lambda di backend.

   Per creare i parametri della stringa di query, procedi come indicato di seguito:

   1. Scegliere **Add query string (Aggiungi stringa di query)**.

   1. In **Nome**, inserisci **operand1**.

   1. Attiva **Campo obbligatorio**.

   1. Mantieni disattivata l'opzione **Caching**.

   Ripeti le stesse fasi e crea una stringa di query denominata **operand2** e una stringa di query denominata **operator**.

1. Scegli **Crea metodo**.

A questo punto crea un modello di mappatura per tradurre le stringhe di query fornite dal client in payload di richiesta di integrazione, come richiesto dalla funzione `Calc`. Questo modello mappa i tre parametri della stringa di query dichiarati in **Richiesta metodo** in valori di proprietà designati dell'oggetto JSON come input per la funzione Lambda di back-end. L'oggetto JSON trasformato verrà incluso come payload di richiesta di integrazione. 

**Per mappare i parametri di input alla richiesta di integrazione**

1. Nella scheda **Richiesta di integrazione** scegli **Modifica** in **Impostazioni della richiesta di integrazione**.

1. Per **Richiesta corpo passthrough** scegli **Quando non ci sono modelli definiti (consigliato)**.

1. Scegli **Modelli di mappatura**.

1. Scegliere **Add mapping template (Aggiungi modello di mappatura)**.

1. Per **Tipo di contenuto** inserisci **application/json**.

1. Per **Corpo del modello** inserisci il seguente codice:

   ```
   {
       "a":  "$input.params('operand1')",
       "b":  "$input.params('operand2')", 
       "op": "$input.params('operator')"   
   }
   ```

1. Scegli **Save** (Salva).

È ora possibile testare il metodo `GET` per verificare che sia stato configurato correttamente per richiamare la funzione Lambda.

**Test del metodo `GET`**

1. Seleziona la scheda **Test**. Potrebbe essere necessario scegliere il pulsante freccia destra per visualizzare la scheda.

1. In **Stringhe di query** immetti **operand1=2&operand2=3&operator=\$1**.

1. Scegli **Test (Esegui test)**.

   I risultati dovrebbero essere simili a quanto segue:  
![\[Creazione di un'API in API Gateway come un proxy Lambda\]](http://docs.aws.amazon.com/it_it/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_new_console.png)

## Integrazione 2: creazione di un metodo `POST` con un payload JSON per chiamare la funzione Lambda
<a name="api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function"></a>

Se si crea un metodo `POST` con un payload JSON per chiamare la funzione Lambda, si richiede al client di fornire l'input necessario alla funzione di back-end nel corpo della richiesta. Per garantire che il client carichi i dati di input corretti, verrà abilitata la convalida delle richieste nel payload.

**Per creare un metodo `POST` con un payload JSON**

1. Seleziona la risorsa **/calc** quindi scegli **Crea metodo**.

1. Per **Tipo di metodo** seleziona **POST**.

1. Per **Tipo di integrazione** seleziona **Servizio AWS**.

1. Per **Regione AWS**, seleziona il Regione AWS luogo in cui hai creato la tua funzione Lambda.

1. Per **Servizio AWS** seleziona **Lambda**.

1. Lascia vuoto **Sottodominio AWS **.

1. Per **Metodo HTTP** seleziona **POST**.

1. In **Tipo di operazione** scegli **Utilizza sostituzione percorso**. Questa opzione permette di specificare l'ARN dell'operazione [Invoke (Richiama)](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) per eseguire la funzione `Calc`. 

1. Per **Sostituzione percorso** immetti **2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**. Per** *account-id***, inserisci il tuo Account AWS ID. Per***us-east-2***, inserisci Regione AWS dove hai creato la tua funzione Lambda. 

1. Per **Ruolo di esecuzione** immetti l'ARN del ruolo per **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

1. Non modificare le impostazioni di **Cache delle credenziali** e **Timeout predefinito**.

1. Scegli **Crea metodo**.

A questo punto crea un modello di **input** per descrivere la struttura dei dati di input e convalidare il corpo della richiesta in ingresso.

**Per creare un modello di input**

1. Nel riquadro di navigazione principale seleziona **Modelli**.

1. Scegli **Crea modello**.

1. In **Nome**, inserisci **input**.

1. Per **Tipo di contenuto** inserisci **application/json**. 

   Se non viene trovato alcun tipo di contenuto corrispondente, la convalida della richiesta non viene eseguita. Per utilizzare lo stesso modello indipendentemente dal tipo di contenuti, inserisci **\$1default**.

1. Per **Schema modello** immetti il seguente modello:

   ```
   {
       "type":"object",
       "properties":{
           "a":{"type":"number"},
           "b":{"type":"number"},
           "op":{"type":"string"}
       },
       "title":"input"
   }
   ```

1. Scegli **Crea modello**.

A questo punto crea un modello di **output**. Questo modello descrive la struttura di dati dell'output calcolato del back-end. Può essere usato per mappare i dati della risposta di integrazione a un modello diverso. Questo tutorial è basato sul comportamento di passthrough e non usa questo modello.

**Per creare un modello di output**

1. Scegli **Crea modello**.

1. In **Nome**, inserisci **output**.

1. Per **Tipo di contenuto** inserisci **application/json**. 

   Se non viene trovato alcun tipo di contenuto corrispondente, la convalida della richiesta non viene eseguita. Per utilizzare lo stesso modello indipendentemente dal tipo di contenuti, inserisci **\$1default**.

1. Per **Schema modello** immetti il seguente modello:

   ```
   {
       "type":"object",
       "properties":{
           "c":{"type":"number"}
       },
       "title":"output"
   }
   ```

1. Scegli **Crea modello**.

A questo punto crea un modello di **risultato**. Questo modello descrive la struttura dei dati della risposta restituiti. Fa riferimento agli schemi di **input** e **output** definiti nell'API.

**Per creare un modello di risultato**

1. Scegli **Crea modello**.

1. In **Nome**, inserisci **result**.

1. Per **Tipo di contenuto** inserisci **application/json**. 

   Se non viene trovato alcun tipo di contenuto corrispondente, la convalida della richiesta non viene eseguita. Per utilizzare lo stesso modello indipendentemente dal tipo di contenuti, inserisci **\$1default**.

1. Per **lo schema del modello**, inserisci il seguente modello con il tuo*restapi-id*. Il tuo *restapi-id* è elencato tra parentesi nella parte superiore della console nel seguente flusso: `API Gateway > APIs > LambdaCalc (abc123).`

   ```
   {
       "type":"object",
       "properties":{
           "input":{
               "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/input"
           },
           "output":{
               "$ref":"https://apigateway.amazonaws.com/restapis/restapi-id/models/output"
           }
       },
       "title":"result"
   }
   ```

1. Scegli **Crea modello**.

A questo punto configura la richiesta del metodo POST per abilitare la convalida della richiesta nel corpo della richiesta in ingresso.

**Abilitazione della convalida della richiesta del metodo POST**

1. Nel pannello di navigazione scegli **Risorse**, quindi seleziona il metodo `POST` nella struttura di risorse.

1. Nella scheda **Richiesta metodo**, in **Impostazioni richiesta metodo**, scegli **Modifica**.

1. Per **Validatore richiesta** seleziona **Convalida corpo**.

1. Scegli **Corpo della richiesta**, quindi seleziona **Aggiungi modello**.

1. Per **Tipo di contenuto** inserisci **application/json**.

   Se non viene trovato alcun tipo di contenuto corrispondente, la convalida della richiesta non viene eseguita. Per utilizzare lo stesso modello indipendentemente dal tipo di contenuti, inserisci **\$1default**.

1. Per **Modello** seleziona **input**.

1. Scegli **Save** (Salva).

È ora possibile testare il metodo `POST` per verificare che sia stato configurato correttamente per richiamare la funzione Lambda.

**Test del metodo `POST`**

1. Seleziona la scheda **Test**. Potrebbe essere necessario scegliere il pulsante freccia destra per visualizzare la scheda.

1. Per **Corpo della richiesta** immetti il payload JSON seguente.

   ```
   {
       "a": 1,
       "b": 2,
       "op": "+"
   }
   ```

1. Scegli **Test (Esegui test)**.

   Verrà visualizzato l’output seguente:

   ```
   {
     "a": 1,
     "b": 2,
     "op": "+",
     "c": 3
   }
   ```

## Integrazione 3: creazione di un metodo `GET` con parametri di percorso per chiamare la funzione Lambda
<a name="api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function"></a>

Verrà ora creato un metodo `GET` in una risorsa specificata da una sequenza di parametri di percorso per chiamare la funzione Lambda di back-end. I valori dei parametri di percorso specificano i dati di input per la funzione Lambda. Verrà usato un modello di mappatura per mappare i valori dei parametri di percorso in ingresso al payload di richiesta di integrazione necessario.

La struttura della risorsa API risultante sarà la seguente:

![\[Creazione di un'API in API Gateway come un proxy Lambda\]](http://docs.aws.amazon.com/it_it/apigateway/latest/developerguide/images/aws_proxy_lambda_create_api_resources_new_console.png)


**Per creare una risorsa **/\$1operand1\$1/\$1operand2\$1/\$1operator\$1****

1. Scegli **Crea risorsa**.

1. Per **Percorso risorsa** seleziona `/calc`.

1. Per **Resource Name (Nome risorsa)** immetti **\$1operand1\$1**.

1. Mantieni **CORS (Cross Origin Resource Sharing)** disattivato.

1. Scegli **Crea risorsa**.

1. Per **Percorso risorsa** seleziona `/calc/{operand1}/`.

1. Per **Resource Name (Nome risorsa)** immetti **\$1operand2\$1**.

1. Mantieni **CORS (Cross Origin Resource Sharing)** disattivato.

1. Scegli **Crea risorsa**.

1. Per **Percorso risorsa** seleziona `/calc/{operand1}/{operand2}/`.

1. Per **Resource Name (Nome risorsa)** immetti **\$1operator\$1**.

1. Mantieni **CORS (Cross Origin Resource Sharing)** disattivato.

1. Scegli **Crea risorsa**.

Questa volta verrà utilizzata l'integrazione Lambda predefinita nella console Gateway API per configurare l'integrazione del metodo.

**Per configurare l'integrazione di un metodo**

1. Seleziona la risorsa **/\$1operand1\$1/\$1operand2\$1/\$1operator\$1**, quindi scegli **Crea metodo**.

1. Per **Tipo di metodo** seleziona **GET**.

1. In **Tipo di integrazione**, seleziona **Lambda**.

1. Mantieni l'opzione **Integrazione proxy Lambda** disattivata.

1. Per la **funzione Lambda**, seleziona il Regione AWS luogo in cui hai creato la funzione Lambda e inserisci. **Calc**

1. Mantieni attivata l'opzione **Timeout predefinito**.

1. Scegli **Crea metodo**.

A questo punto crea il modello per mappare i tre parametri del percorso URL, dichiarati quando è stata creata la risorsa **/calc/\$1operand1\$1/\$1operand2\$1/\$1operator\$1**, ai valori di proprietà designati nell'oggetto JSON. Poiché i percorsi URL devono essere codificati in formato URL, l'operatore di divisione deve essere specificato come `%2F` invece di `/`. Questo modello traduce `%2F` in `'/'` prima di passarlo alla funzione Lambda. 

**Per creare un modello di mappatura**

1. Nella scheda **Richiesta di integrazione** scegli **Modifica** in **Impostazioni della richiesta di integrazione**.

1. Per **Richiesta corpo passthrough** scegli **Quando non ci sono modelli definiti (consigliato)**.

1. Scegli **Modelli di mappatura**.

1. Per **Tipo di contenuto** inserisci **application/json**.

1. Per **Corpo del modello** inserisci il seguente codice:

   ```
   {
      "a": "$input.params('operand1')",
      "b": "$input.params('operand2')",
      "op": #if($input.params('operator')=='%2F')"/"#{else}"$input.params('operator')"#end
   }
   ```

1. Scegli **Save** (Salva).

A questo punto testa il metodo `GET` per verificare che sia stato configurato correttamente per richiamare la funzione Lambda e passare l'output originale con la risposta di integrazione senza mappatura. 

**Test del metodo `GET`**

1. Seleziona la scheda **Test**. Potrebbe essere necessario scegliere il pulsante freccia destra per visualizzare la scheda.

1. Per **Percorso** procedi come segue:

   1. Per **operand1** immetti **1**.

   1. Per **operand2** immetti **1**.

   1. Per **operator** immetti **\$1**.

1. Scegli **Test (Esegui test)**.

1. Il risultato deve essere simile al seguente:  
![\[Test del metodo GET nella console Gateway API.\]](http://docs.aws.amazon.com/it_it/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_path_parm_new_console.png)

A questo punto modella la struttura di dati del payload di risposta del metodo dopo lo schema `result`.

Per impostazione predefinita, al corpo della risposta del metodo viene assegnato un modello vuoto. Di conseguenza, il corpo della risposta di integrazione viene passato senza mappatura. Tuttavia, quando generi un SDK per uno dei linguaggi fortemente tipizzati, ad esempio Java o Objective-C, gli utenti dell'SDK riceveranno un oggetto vuoto come risultato. Affinché sia il client REST che i client SDK ricevano il risultato desiderato, è necessario modellare i dati della risposta utilizzando uno schema predefinito. Verrà illustrato come definire un modello per il corpo della risposta del metodo e creare un modello di mappatura per convertire il corpo della risposta di integrazione nel corpo della risposta del metodo.

**Per creare una risposta del metodo**

1. Nella scheda **Risposta metodo** scegli **Modifica** in **Risposta 200**.

1. In **Corpo della risposta** scegli **Aggiungi modello**.

1. Per **Tipo di contenuto** inserisci **application/json**.

1. Per **Modello** seleziona **risultato**.

1. Scegli **Save** (Salva).

L'impostazione del modello per il corpo della risposta del metodo assicura che i dati della risposta verranno trasmessi nell'oggetto `result` di un determinato SDK. Per fare in modo che i dati della risposta di integrazione siano mappati di conseguenza, è necessario un modello di mappatura.

**Per creare un modello di mappatura**

1. Nella scheda **Risposta di integrazione** scegli **Modifica** in **Predefinito - Risposta**.

1. Scegli **Modelli di mappatura**.

1. Per **Tipo di contenuto** inserisci **application/json**.

1. Per **Corpo del modello** inserisci il seguente codice:

   ```
   #set($inputRoot = $input.path('$'))
   {
     "input" : {
       "a" : $inputRoot.a,
       "b" : $inputRoot.b,
       "op" : "$inputRoot.op"
     },
     "output" : {
       "c" : $inputRoot.c
     }
   }
   ```

1. Scegli **Save** (Salva).

**Per testare il modello di mappatura**

1. Seleziona la scheda **Test**. Potrebbe essere necessario scegliere il pulsante freccia destra per visualizzare la scheda.

1. Per **Percorso** procedi come segue:

   1. Per **operand1** immetti **1**.

   1. Per **operand2** immetti **2**.

   1. Per **operator** immetti **\$1**.

1. Scegli **Test (Esegui test)**.

1. Il risultato sarà simile al seguente:

   ```
   {
     "input": {
       "a": 1,
       "b": 2,
       "op": "+"
     },
     "output": {
       "c": 3
     }
   }
   ```

A questo punto puoi chiamare l'API solo tramite la funzionalità **Test** nella console Gateway API. Per rendere l'API disponibile per i client, è necessario distribuirla. Assicurarsi sempre di ridistribuire l'API ogni volta che si aggiunge, si modifica o si elemina una risorsa o un metodo, si aggiorna una mappatura dei dati o si aggiornano le impostazioni della fase. In caso contrario, le nuove funzionalità o gli aggiornamenti non saranno disponibili per i client dell'API, come indicato di seguito:

**Per distribuire l'API**

1. Seleziona **Deploy API (Distribuisci API)**.

1. In **Fase**, seleziona **Nuova fase**.

1. In **Stage name (Nome fase)** immettere **Prod**.

1. (Facoltativo) In **Descrizione**, immetti una descrizione.

1. Seleziona **Implementa**.

1.  (Facoltativo) In **Dettagli fase** puoi scegliere l'icona Copia per copiare l'URL di richiamata dell'API in **Richiama URL**. È possibile usare questo valore con strumenti come [Postman](https://www.postman.com) e [cURL](https://curl.se/) per testare l'API.

**Nota**  
Implementa nuovamente l'API ogni volta che aggiungi, modifichi o elemini una risorsa o un metodo e aggiorni una mappatura dei dati oppure le impostazioni della fase. In caso contrario, le nuove caratteristiche o gli aggiornamenti non saranno disponibili per i client dell'API.

# Definizioni OpenAPI di un'API di esempio integrata con una funzione Lambda
<a name="api-as-lambda-proxy-export-swagger-with-extensions"></a>

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger": "2.0",
  "info": {
    "version": "2017-04-20T04:08:08Z",
    "title": "LambdaCalc"
  },
  "host": "uojnr9hd57.execute-api.us-east-1.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/calc": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "operand2",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "operator",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "operand1",
            "in": "query",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            },
            "headers": {
              "operand_1": {
                "type": "string"
              },
              "operand_2": {
                "type": "string"
              },
              "operator": {
                "type": "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator": "Validate query string parameters and headers",
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.operator": "integration.response.body.op",
                "method.response.header.operand_2": "integration.response.body.b",
                "method.response.header.operand_1": "integration.response.body.a"
              },
              "responseTemplates": {
                "application/json": "#set($res = $input.path('$'))\n{\n    \"result\": \"$res.a, $res.b, $res.op => $res.c\",\n  \"a\" : \"$res.a\",\n  \"b\" : \"$res.b\",\n  \"op\" : \"$res.op\",\n  \"c\" : \"$res.c\"\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n    \"a\":  \"$input.params('operand1')\",\n    \"b\":  \"$input.params('operand2')\", \n    \"op\": \"$input.params('operator')\"   \n}"
          },
          "type": "aws"
        }
      },
      "post": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "body",
            "name": "Input",
            "required": true,
            "schema": {
              "$ref": "#/definitions/Input"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            }
          }
        },
        "x-amazon-apigateway-request-validator": "Validate body",
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($inputRoot = $input.path('$'))\n{\n  \"a\" : $inputRoot.a,\n  \"b\" : $inputRoot.b,\n  \"op\" : $inputRoot.op,\n  \"c\" : $inputRoot.c\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "type": "aws"
        }
      }
    },
    "/calc/{operand1}/{operand2}/{operator}": {
      "get": {
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "operand2",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "operator",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "operand1",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Result"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($inputRoot = $input.path('$'))\n{\n  \"input\" : {\n    \"a\" : $inputRoot.a,\n    \"b\" : $inputRoot.b,\n    \"op\" : \"$inputRoot.op\"\n  },\n  \"output\" : {\n    \"c\" : $inputRoot.c\n  }\n}"
              }
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:Calc/invocations",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n   \"a\": \"$input.params('operand1')\",\n   \"b\": \"$input.params('operand2')\",\n   \"op\": #if($input.params('operator')=='%2F')\"/\"#{else}\"$input.params('operator')\"#end\n   \n}"
          },
          "contentHandling": "CONVERT_TO_TEXT",
          "type": "aws"
        }
      }
    }
  },
  "definitions": {
    "Input": {
      "type": "object",
      "required": [
        "a",
        "b",
        "op"
      ],
      "properties": {
        "a": {
          "type": "number"
        },
        "b": {
          "type": "number"
        },
        "op": {
          "type": "string",
          "description": "binary op of ['+', 'add', '-', 'sub', '*', 'mul', '%2F', 'div']"
        }
      },
      "title": "Input"
    },
    "Output": {
      "type": "object",
      "properties": {
        "c": {
          "type": "number"
        }
      },
      "title": "Output"
    },
    "Result": {
      "type": "object",
      "properties": {
        "input": {
          "$ref": "#/definitions/Input"
        },
        "output": {
          "$ref": "#/definitions/Output"
        }
      },
      "title": "Result"
    }
  },
  "x-amazon-apigateway-request-validators": {
    "Validate body": {
      "validateRequestParameters": false,
      "validateRequestBody": true
    },
    "Validate query string parameters and headers": {
      "validateRequestParameters": true,
      "validateRequestBody": false
    }
  }
}
```

------