

# Tutorial: Criar uma API REST de calculadora com duas integrações de serviços da AWS e uma integração sem proxy do Lambda
<a name="integrating-api-with-aws-services-lambda"></a>

O [Tutorial: Crie uma API REST com uma integração de não proxy do Lambda](getting-started-lambda-non-proxy-integration.md) usa a integração `Lambda Function` exclusivamente. A integração `Lambda Function` é um caso especial do tipo de integração do `AWS Service` que executa grande parte da configuração de integração para você, como adicionar automaticamente as permissões necessárias com base em recursos para invocar a função do Lambda. Aqui, duas das três integrações usam a integração `AWS Service` Nesse tipo de integração, você tem mais controle, mas precisará executar tarefas manualmente, como criar e especificar uma função do IAM que contém as permissões adequadas.



Neste tutorial, você criará uma função do Lambda `Calc` que implementa operações aritméticas básicas, aceitando e retornando a entrada e a saída formatadas em JSON. Você vai criar uma API REST e integrá-la à função do Lambda das seguintes formas:

1. Ao expor um método `GET` no recurso `/calc` para invocar a função do Lambda, fornecendo a entrada como parâmetros de string de consulta. (Integração `AWS Service`)

1. Ao expor um método `POST` no recurso `/calc` para invocar a função do Lambda, fornecendo a entrada na carga de solicitação do método. (Integração `AWS Service`)

1. Ao expor um `GET` em recursos `/calc/{operand1}/{operand2}/{operator}` aninhados para invocar a função do Lambda, fornecendo a entrada como parâmetros de caminho. (Integração `Lambda Function`)

Além de experimentar este tutorial, talvez você queira estudar o [arquivo de definição do OpenAPI](api-as-lambda-proxy-export-swagger-with-extensions.md) para a API `Calc`, que pode ser importado para o API Gateway seguindo as instruções em [Desenvolver APIs REST usando OpenAPI no API Gateway](api-gateway-import-api.md).

**Topics**
+ [Criar uma função do IAM que pode ser assumida](#api-as-lambda-proxy-setup-iam-role-policies)
+ [Criar uma função do Lambda `Calc`](#api-as-lambda-proxy-create-lambda-function)
+ [Testar a função do Lambda `Calc`](#api-as-lambda-proxy-test-lambda-function-)
+ [Criar uma API `Calc`](#api-as-lambda-proxy-create-api-resources)
+ [Integração 1: Criar um método `GET` com parâmetros de consulta para chamar a função do Lambda](#api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function)
+ [Integração 2: Criar um método `POST` com uma carga JSON para chamar a função do Lambda](#api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function)
+ [Integração 3: Criar um método `GET` com parâmetros de caminho para chamar a função do Lambda](#api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function)
+ [Definições do OpenAPI da API demonstrativa integrada com uma função do Lambda](api-as-lambda-proxy-export-swagger-with-extensions.md)

## Criar uma função do IAM que pode ser assumida
<a name="api-as-lambda-proxy-setup-iam-role-policies"></a>

Para que sua API invoque sua função do Lambda `Calc`, você precisará ter uma função do IAM do API Gateway que pode ser assumida, que é uma função do IAM com o seguinte relacionamento confiável:

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

****  

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

------

A função criada precisará ter uma permissão do Lambda [InvokeFunction](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html). Caso contrário, o autor da chamada de API receberá uma resposta `500 Internal Server Error`. Para conceder essa permissão à função, você anexará a política do IAM a ela:

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

****  

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

------

Veja a seguir como fazer isso:

**Criar uma função do IAM do API Gateway que possa ser assumida**

1. Faça login no console do IAM.

1. Escolha **Roles**.

1. Selecione **Create Role**.

1. Em **Select type of trusted entity** (Selecionar tipo de entidade confiável), selecione **AWS Serviço**.

1. Em **Choose the service that will use this role** (Escolha o serviço que usará essa função), escolha **Lambda**.

1. Escolha **Next: Permissions** (Próximo: Permissões).

1. Selecione **Create Policy** (Criar política).

   Uma nova janela do console **Create Policy** (Criar Política) será aberta. Nessa janela, faça o seguinte:

   1. Na guia **JSON**, substitua a política existente pela política a seguir:

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

****  

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

------

   1. Escolha **Review policy** (Revisar política).

   1. Em **Review Policy (Revisar política)**, faça o seguinte:

      1. Em **Name**, digite um nome de usuário, como **lambda\$1execute**.

      1. Selecione **Create Policy** (Criar política).

1. Na janela do console **Create Role (Criar função)** original, faça o seguinte:

   1. Em **Attach permissions policies (Anexar permissões políticas)**, escolha a política **lambda\$1execute** na lista suspensa.

      Se você não vir a política na lista, selecione o botão Atualizar na parte superior da lista. (Não atualize a página do navegador.)

   1. Selecione **Next: Tags (Próximo: tags)**.

   1. Selecione **Next:Review (Próximo: análise)**.

   1. Em **Role name (Nome da função)**, digite um nome como **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

   1. Selecione **Create role**.

1. Escolha **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** na lista de funções.

1. Selecione a guia **Trust relationships (Relações de confiança)**.

1. Escolha **Edit trust relationship (Editar relação de confiança)**.

1. Substitua a política existente pela seguinte:

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

****  

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

------

1. Escolha **Update Trust Policy**.

1. Anote o ARN da função para a função que acabou de criar. Você precisará disso mais tarde.

## Criar uma função do Lambda `Calc`
<a name="api-as-lambda-proxy-create-lambda-function"></a>

Depois, você criará uma função do Lambda usando o console do Lambda.

1. No console do Lambda, escolha **Create function (Criar função)**.

1. Escolha **Author from Scratch**.

1. Em **Name (Nome)**, insira **Calc**.

1. Em **Tempo de execução**, escolha o último runtime **Node.js** ou **Python** compatível.

1. Em todas as outras opções, use a configuração padrão.

1. Escolha a opção **Criar função**.

1.  Copie a função do Lambda a seguir em seu runtime preferido e cole-a no editor de código do console do 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. Em Execution role (Função de execução), selecione **Choose an existing role (Selecionar uma função existente)**.

1. Insira o ARN da função para a função **lambda\$1invoke\$1function\$1assume\$1apigw\$1role** que você criou anteriormente.

1. Escolha **Deploy** (Implantar).

 Essa função requer dois operandos (`a` e `b`) e um operador (`op`) a partir do parâmetro de entrada `event`. A entrada é um objeto JSON no seguinte formato: 

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

Essa função retorna o resultado calculado (`c`) e a entrada. Para uma entrada inválida, a função retorna o valor nulo ou a string "Invalid op" como resultado. A saída é do seguinte formato JSON: 

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

É necessário testar a função no console do Lambda antes de integrá-la à API na próxima etapa. 

## Testar a função do Lambda `Calc`
<a name="api-as-lambda-proxy-test-lambda-function-"></a>

Veja a seguir como testar a função `Calc` no console do Lambda:

1. Selecione a guia **Testar**.

1. Para o nome de evento de teste, insira **calc2plus5**.

1. Substitua a definição de eventos de teste pelo seguinte:

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

1. Escolha **Save** (Salvar).

1. Escolha **Test** (Testar).

1. Expanda **Execution result: succeeded (Resultado da execução: com êxito)**. Você deve ver o seguinte:

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

## Criar uma API `Calc`
<a name="api-as-lambda-proxy-create-api-resources"></a>

O procedimento a seguir mostra como criar uma API para a função do Lambda `Calc` que você acabou de criar. Nas seções a seguir, você adicionará recursos e métodos a ela.

**Como criar uma API**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Se esta for a primeira vez que você usa o API Gateway, você verá uma página com os recursos do serviço. Em **REST API**, escolha **Build** (Criar). Quando o pop-up **Create Example API** (Criar API de exemplo) for exibido, escolha **OK**.

   Se essa não for a primeira vez que você usa o API Gateway, escolha **Create API** (Criar API). Em **REST API**, escolha **Build** (Criar).

1.  Em **API name (Nome da API)**, insira **LambdaCalc**.

1. (Opcional) Em **Description (Descrição)**, insira uma descrição.

1. Mantenha **Tipo de endpoint de API** definido como **Regional**.

1. Em **Tipo de endereço IP**, selecione **IPv4**.

1. Selecione **Create API** (Criar API).

## Integração 1: Criar um método `GET` com parâmetros de consulta para chamar a função do Lambda
<a name="api-as-lambda-proxy-expose-get-method-with-query-strings-to-call-lambda-function"></a>

Ao criar um método `GET` que transmita parâmetros de string de consulta para a função do Lambda, habilite a API para ser invocada de um navegador. Essa abordagem pode ser útil, especialmente para APIs que permitem acesso aberto.

Depois de criar uma API, você criará um recurso. Normalmente, os recursos da API são organizados em uma árvore de recursos, de acordo com a lógica do aplicativo. Para esta etapa, você vai criar um recurso **/calc**. 

**Como criar um recurso **/calc****

1. Selecione **Criar recurso**.

1. Mantenha **Recurso proxy** desativado. 

1. Mantenha **Caminho do recurso** como `/`.

1. Em **Resource Name (Nome do recurso)**, insira **calc**.

1. Mantenha **CORS (Compartilhamento de recursos de origem cruzada)** desativado.

1. Selecione **Criar recurso**.

Ao criar um método `GET` que transmita parâmetros de string de consulta para a função do Lambda, habilite a API para ser invocada de um navegador. Essa abordagem pode ser útil, especialmente para APIs que permitem acesso aberto.

Neste método, o Lambda requer que a solicitação `POST` seja usada para invocar qualquer função do Lambda. Esse exemplo mostra que o método HTTP em uma solicitação de método de front-end pode ser diferente da solicitação de integração no backend.

**Como criar um método `GET`**

1. Selecione o recurso **/calc** e **Criar método**.

1. Em **Tipo de método**, selecione **GET**.

1. Em **Tipo de integração**, selecione **AWS service (Serviço da AWS)**.

1. Em **Região da AWS**, selecione a Região da AWS onde você criou a função do Lambda.

1. Em **AWS service (Serviço da AWS)**, selecione **Lambda**.

1. Mantenha o **subdomínio da AWS** em branco.

1. Em **Método HTTP**, selecione **POST**.

1. Em **Tipo de ação**, escolha **Usar substituição de caminho**. Essa opção nos permite especificar o ARN da ação [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) para executar nossa função `Calc`. 

1. Em **Substituição de caminho**, digite **2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**. Em ** *account-id***, insira o ID da Conta da AWS. Em ***us-east-2***, insira a Região da AWS onde você criou a função do Lambda. 

1. Em **Perfil de execução**, digite o ARN do perfil para **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

1. Não altere as configurações do **Cache de credenciais** e do **Tempo limite padrão**.

1. Escolha **Configurações de solicitação de método**.

1. Em **Validador de solicitação**, selecione **Validar parâmetros de string de consulta e cabeçalhos**.

   Essa configuração fará com que uma mensagem de erro seja gerada se o cliente não especificar os parâmetros necessários.

1. Selecione **Parâmetros de string de consulta de URL**.

   Agora configure parâmetros de string de consulta para o método **GET** no recurso **/calc** para que ele possa receber a entrada em nome da função do Lambda de back-end.

   Para criar parâmetros de string de consulta, faça o seguinte:

   1. Escolha **Add query string** (Adicionar string de consulta).

   1. Em **Nome**, digite **operand1**.

   1. Ative a opção **Obrigatório**.

   1. Mantenha **Armazenamento em cache** desativado.

   Repita as mesmas etapas e crie uma string de consulta chamada **operand2** e uma string de consulta chamada **operator**.

1. Escolha **Criar método**.

Agora, você vai criar um modelo de mapeamento para converter as strings de consulta fornecidas pelo cliente na carga útil de solicitações de integração, conforme exigido pela função `Calc`. Esse modelo associa os três parâmetros de consulta declarados em **Solicitação de método** a valores de propriedade designados do objeto JSON como entrada para a função do Lambda de back-end. O objeto JSON transformado será incluído como a carga útil da solicitação de integração. 

**Como associar parâmetros de entrada à solicitação de integração**

1. Na guia **Solicitação de integração**, em **Configurações de solicitação de integração**, selecione **Editar**.

1. Em **Passagem do corpo da solicitação**, selecione **Quando não há modelos definidos (recomendado)**.

1. Selecione **Modelos de mapeamento**.

1. Escolha **Add mapping template** (Adicionar modelo de mapeamento).

1. Em **Tipo de conteúdo**, insira **application/json**.

1. Em **Corpo do modelo**, insira o seguinte código:

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

1. Escolha **Salvar**.

Agora, é possível testar o método `GET` para verificar se ele foi configurado corretamente para invocar a função do Lambda:

**Como testar o método `GET`**

1. Selecione a guia **Testar**. Talvez seja necessário selecionar o botão de seta para a direita para mostrar a guia.

1. Em **Strings de consulta**, digite **operand1=2&operand2=3&operator=\$1**.

1. Escolha **Test** (Testar).

   Os resultados devem ser semelhantes ao seguinte:  
![\[Criar uma API no API Gateway como um proxy do Lambda\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_new_console.png)

## Integração 2: Criar um método `POST` com uma carga JSON para chamar a função do Lambda
<a name="api-as-lambda-proxy-expose-post-method-with-json-body-to-call-lambda-function"></a>

Depois da criação de um método `POST` com uma carga JSON para chamar a função do Lambda, o cliente deve enviar a entrada necessária para a função de backend no corpo da solicitação. Para garantir que o cliente faça upload dos dados de entrada corretos, você habilitará a validação de solicitações na carga.

**Como criar um método `POST` com uma carga útil do JSON**

1. Selecione o recurso **/calc** e **Criar método**.

1. Em **Tipo de método**, selecione **POST**.

1. Em **Tipo de integração**, selecione **AWS service (Serviço da AWS)**.

1. Em **Região da AWS**, selecione a Região da AWS onde você criou a função do Lambda.

1. Em **AWS service (Serviço da AWS)**, selecione **Lambda**.

1. Mantenha o **subdomínio da AWS** em branco.

1. Em **Método HTTP**, selecione **POST**.

1. Em **Tipo de ação**, escolha **Usar substituição de caminho**. Essa opção nos permite especificar o ARN da ação [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) para executar nossa função `Calc`. 

1. Em **Substituição de caminho**, digite **2015-03-31/functions/arn:aws:lambda:*us-east-2*:*account-id*:function:Calc/invocations**. Em ** *account-id***, insira o ID da Conta da AWS. Em ***us-east-2***, insira a Região da AWS onde você criou a função do Lambda. 

1. Em **Perfil de execução**, digite o ARN do perfil para **lambda\$1invoke\$1function\$1assume\$1apigw\$1role**.

1. Não altere as configurações do **Cache de credenciais** e do **Tempo limite padrão**.

1. Escolha **Criar método**.

Agora você vai criar um modelo de **entrada** para descrever a estrutura de dados de entrada e validar o corpo da solicitação recebida.

**Como criar o modelo de entrada**

1. No painel de navegação principal, selecione **Modelos**.

1. Escolha **Criar modelo**.

1. Em **Nome**, digite **input**.

1. Em **Tipo de conteúdo**, insira **application/json**. 

   Se nenhum tipo de conteúdo correspondente for encontrado, a validação da solicitação não será executada. Para usar o mesmo modelo, independentemente do tipo de conteúdo, insira  **\$1default**.

1. Em **Esquema do modelo**, insira o seguinte modelo:

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

1. Escolha **Criar modelo**.

Agora você vai criar um modelo de **saída**. Esse modelo descreve a estrutura de dados da saída calculada do backend. Ele pode ser usado para mapear dados de resposta de integração para um modelo diferente. Este tutorial depende do comportamento de passagem direta e não usa este modelo.

**Como criar um modelo de saída**

1. Escolha **Criar modelo**.

1. Em **Nome**, digite **output**.

1. Em **Tipo de conteúdo**, insira **application/json**. 

   Se nenhum tipo de conteúdo correspondente for encontrado, a validação da solicitação não será executada. Para usar o mesmo modelo, independentemente do tipo de conteúdo, insira  **\$1default**.

1. Em **Esquema do modelo**, insira o seguinte modelo:

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

1. Escolha **Criar modelo**.

Agora você vai criar um modelo de **resultado**. Esse modelo descreve a estrutura de dados dos dados de resposta retornados. Ele faz referência aos esquemas de **entrada** e de **saída** definidos na API.

**Como criar um modelo de resultado**

1. Escolha **Criar modelo**.

1. Em **Nome**, digite **result**.

1. Em **Tipo de conteúdo**, insira **application/json**. 

   Se nenhum tipo de conteúdo correspondente for encontrado, a validação da solicitação não será executada. Para usar o mesmo modelo, independentemente do tipo de conteúdo, insira  **\$1default**.

1. Em **Esquema do modelo**, insira o modelo a seguir com o *restapi-id*. O *restapi-id* está listado entre parênteses na parte superior do console no seguinte fluxo: `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. Escolha **Criar modelo**.

Agora, você vai configurar a solicitação do método POST para habilitar a validação de solicitações no corpo da solicitação recebida.

**Habilitar a validação da solicitação no método POST**

1. No painel de navegação principal, selecione **Recursos** e, depois, selecione o método `POST` na árvore de recursos.

1. Na guia **Solicitação de método**, em **Configurações de solicitação de método**, escolha **Editar**.

1. Em **Validador de solicitação**, selecione **Validar corpo.**

1. Selecione **Corpo da solicitação** e, depois, **Adicionar modelo**.

1. Em **Tipo de conteúdo**, insira **application/json**.

   Se nenhum tipo de conteúdo correspondente for encontrado, a validação da solicitação não será executada. Para usar o mesmo modelo, independentemente do tipo de conteúdo, insira  **\$1default**.

1. Em **Modelo**, selecione **entrada**.

1. Escolha **Salvar**.

Agora, é possível testar o método `POST` para verificar se ele foi configurado corretamente para invocar a função do Lambda:

**Como testar o método `POST`**

1. Selecione a guia **Testar**. Talvez seja necessário selecionar o botão de seta para a direita para mostrar a guia.

1. Em **Corpo da solicitação**, insira a carga útil do JSON a seguir.

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

1. Escolha **Testar**.

   A seguinte saída deverá ser mostrada:

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

## Integração 3: Criar um método `GET` com parâmetros de caminho para chamar a função do Lambda
<a name="api-as-lambda-proxy-expose-get-method-with-path-parameters-to-call-lambda-function"></a>

Agora, você criará um método `GET` em um recurso especificado por uma sequência de parâmetros de caminho para chamar a função do Lambda de backend. Os valores de parâmetros de caminho especificam os dados de entrada para a função do Lambda. Você usará um modelo de mapeamento para mapear os valores de parâmetro de caminho de entrada para a carga necessária de solicitação de integração.

A aparência da estrutura de recursos de API resultante será semelhante a esta:

![\[Criar uma API no API Gateway como um proxy do Lambda\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/aws_proxy_lambda_create_api_resources_new_console.png)


**Como criar um recurso**/\$1operand1\$1/\$1operand2\$1/\$1operator\$1****

1. Selecione **Criar recurso**.

1. Em **Caminho do recurso**, selecione `/calc`.

1. Em **Resource Name (Nome do recurso)**, insira **\$1operand1\$1**.

1. Mantenha **CORS (Compartilhamento de recursos de origem cruzada)** desativado.

1. Selecione **Criar recurso**.

1. Em **Caminho do recurso**, selecione `/calc/{operand1}/`.

1. Em **Resource Name (Nome do recurso)**, insira **\$1operand2\$1**.

1. Mantenha **CORS (Compartilhamento de recursos de origem cruzada)** desativado.

1. Selecione **Criar recurso**.

1. Em **Caminho do recurso**, selecione `/calc/{operand1}/{operand2}/`.

1. Em **Resource Name (Nome do recurso)**, insira **\$1operator\$1**.

1. Mantenha **CORS (Compartilhamento de recursos de origem cruzada)** desativado.

1. Selecione **Criar recurso**.

Dessa vez, você usará a integração do Lambda incorporada no console do API Gateway para configurar a integração do método.

**Como configurar uma integração de método**

1. Selecione o recurso **/\$1operand1\$1/\$1operand2\$1/\$1operator\$1** e, depois, escolha **Criar método**.

1. Em **Tipo de método**, selecione **GET**.

1. Em **Tipo de integração**, selecione **Lambda**.

1. Mantenha a opção **Integração do proxy do Lambda** desativada.

1. Em **Função do Lambda**, selecione a Região da AWS onde você criou a função do Lambda e insira **Calc**.

1. Mantenha o **Tempo limite padrão** ativado.

1. Escolha **Criar método**.

Agora, você vai criar um modelo de mapeamento para associar os três parâmetros de caminho de URL, declarados quando o recurso **/calc/\$1operand1\$1/\$1operand2\$1/\$1operator\$1** foi criado, a valores de propriedade designados no objeto JSON. Como os caminhos de URL devem ser codificados em URL, o operador de divisão deve ser especificado como `%2F` em vez de `/`. Esse modelo converte o `%2F` em `'/'` antes de transferi-lo para a função do Lambda. 

**Como criar um modelo de mapeamento**

1. Na guia **Solicitação de integração**, em **Configurações de solicitação de integração**, selecione **Editar**.

1. Em **Passagem do corpo da solicitação**, selecione **Quando não há modelos definidos (recomendado)**.

1. Selecione **Modelos de mapeamento**.

1. Em **Tipo de conteúdo**, insira **application/json**.

1. Em **Corpo do modelo**, insira o seguinte código:

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

1. Escolha **Salvar**.

Agora, é possível testar o método `GET` para verificar se ele foi configurado corretamente para invocar a função do Lambda e passar a saída original pela resposta de integração sem mapeamento. 

**Como testar o método `GET`**

1. Selecione a guia **Testar**. Talvez seja necessário selecionar o botão de seta para a direita para mostrar a guia.

1. Para o **Caminho**, faça o seguinte:

   1. Em **operand1**, insira **1**.

   1. Em **operand2**, insira **1**.

   1. Em **operador**, insira **\$1**.

1. Escolha **Test** (Testar).

1. O resultado deve ser semelhante ao seguinte:  
![\[Teste o método GET no console do API Gateway.\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/aws_proxy_lambda_calc_get_method_test_path_parm_new_console.png)

Depois, você modelará a estrutura de dados da carga útil de resposta de método após o esquema `result`.

Por padrão, o corpo de resposta de método recebe um modelo vazio. Isso fará com que o corpo de resposta de integração seja repassado sem mapeamento. No entanto, quando você gerar um SDK para uma das linguagens de tipo forte, como Java ou Objective-C, os usuários do seu SDK receberão um objeto vazio como resultado. Para garantir que tanto o cliente REST quanto os clientes do SDK recebam o resultado desejado, você deve modelar os dados de resposta usando uma esquema predefinido. Aqui, você definirá um modelo para o corpo de resposta de método e para construir um modelo de mapeamento a fim de traduzir o corpo da resposta de integração no corpo da resposta de método.

**Como criar uma resposta de método**

1. Na guia **Resposta de método**, em **Resposta 200**, selecione **Editar**.

1. Em **Corpo da resposta**, selecione **Adicionar modelo**.

1. Em **Tipo de conteúdo**, insira **application/json**.

1. Em **Modelo**, selecione o **resultado**.

1. Escolha **Salvar**.

Definir o modelo `result` para o corpo da resposta de método garante que os dados da resposta serão convertidos no objeto de um determinado SDK. Para garantir que os dados de resposta de integração sejam mapeados de acordo, você precisará de um modelo de mapeamento.

**Como criar um modelo de mapeamento**

1. Na guia **Resposta de integração**, em **Padrão - Resposta**, selecione **Editar**.

1. Selecione **Modelos de mapeamento**.

1. Em **Tipo de conteúdo**, insira **application/json**.

1. Em **Corpo do modelo**, insira o seguinte código:

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

1. Escolha **Salvar**.

**Como testar o modelo de mapeamento**

1. Selecione a guia **Testar**. Talvez seja necessário selecionar o botão de seta para a direita para mostrar a guia.

1. Para o **Caminho**, faça o seguinte:

   1. Em **operand1**, insira **1**.

   1. Em **operand2**, insira **2**.

   1. Em **operador**, insira **\$1**.

1. Escolha **Testar**.

1. O resultado terá esta aparência:

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

Nesse momento, somente é possível chamar a API usando o atributo **Testar** no console do API Gateway. Para disponibilizá-la para os clientes, será necessário implantar a API. Certifique-se de reimplantar sua API sempre que você adicionar, modificar ou excluir um recurso ou método, atualizar um mapeamento de dados ou atualizar as configurações de estágio. Caso contrário, novos atributos ou atualizações não estarão disponíveis para clientes da API.

**Para implantar a API**

1. Escolha **Implantar API**.

1. Em **Estágio**, selecione **Novo estágio**.

1. Em **Stage name (Nome do estágio)**, insira **Prod**.

1. (Opcional) Em **Description (Descrição)**, insira uma descrição.

1. Escolha **Implantar**.

1.  (Opcional) Em **Detalhes do estágio**, para **Invocar URL**, é possível selecionar o ícone de cópia para copiar o URL de invocação da API. Você pode usá-lo com ferramentas, como [Postman](https://www.postman.com) e [cURL](https://curl.se/) para testar sua API.

**nota**  
Reimplante a API sempre que você adicionar, modificar ou excluir um recurso ou um método, atualizar um mapeamento de dados ou atualizar as configurações de estágio. Caso contrário, novos recursos ou atualizações não estarão disponíveis para clientes de sua API.

# Definições do OpenAPI da API demonstrativa integrada com uma função do 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
    }
  }
}
```

------