

# Tutorial: modificar a solicitação e a resposta de integração para integrações a serviços da AWS
<a name="set-up-data-transformations-in-api-gateway"></a>

O tutorial a seguir mostra como usar transformações de modelos de mapeamento para configurar modelos de mapeamento a fim de transformar solicitações e respostas de integração usando o console e a AWS CLI.

**Topics**
+ [Configurar transformações de dados no console do API Gateway](#mapping-example-console)
+ [Configurar a transformação de dados usando a CLI da AWS](#mapping-example-cli)
+ [Modelo CloudFormation de transformação de dados concluído](#api-gateway-data-transformations-full-cfn-stack)

## Configurar transformações de dados no console do API Gateway
<a name="mapping-example-console"></a>

Neste tutorial, você criará uma API incompleta e uma tabela do DynamoDB usando o seguinte arquivo .zip [data-transformation-tutorial-console.zip](samples/data-transformation-tutorial-console.zip). Essa API incompleta tem um recurso `/pets` com os métodos `GET` e `POST`. 
+ O método `GET` obterá dados do endpoint HTTP `http://petstore-demo-endpoint.execute-api.com/petstore/pets`. Os dados de saída serão transformados de acordo com o modelo de mapeamento em  [Transformações de modelo de mapeamento para APIs REST no API Gateway](models-mappings.md).
+ O método `POST` possibilitará que o usuário `POST` informações sobre animais de estimação em uma tabela do Amazon DynamoDB usando um modelo de mapeamento.

Baixe e descompacte [o modelo de criação de aplicativos para CloudFormation](samples/data-transformation-tutorial-console.zip). Você usará esse modelo para criar uma tabela do DynamoDB para publicar informações sobre animais de estimação e uma API incompleta. Você concluirá o restante das etapas no console do API Gateway. 

**Como criar uma pilha do CloudFormation**

1. Abra o console do CloudFormation em [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Selecione **Create stack (Criar pilha)** e **With new resources (standard) (Com novos recursos (padrão))**.

1. Em **Specify template (Especificar modelo)**, escolha **Upload a template file (Fazer upload de um arquivo de modelo)**.

1. Selecione o modelo que você baixou.

1. Escolha **Next (Próximo)**. 

1. Em **Nome da pilha**, insira **data-transformation-tutorial-console** e escolha **Avançar**.

1. Para **Configurar opções de pilha**, escolha **Avançar**.

1. Para **Capabilities** (Recursos), reconheça que CloudFormation pode criar recursos do IAM em sua conta.

1. Escolha **Próximo** e, depois, **Enviar**.

CloudFormationO fornece os recursos especificados no modelo. Pode demorar alguns minutos para concluir o provisionamento de seus recursos. Quando o status da sua pilha do CloudFormation for **CREATE\$1COMPLETE**, você estará pronto para passar para a próxima etapa.

**Como testar a resposta de integração `GET`**

1. Na guia **Recursos** da pilha de CloudFormation para **data-transformation-tutorial-console**, selecione o ID físico de sua API.

1. No painel de navegação, selecione **Recursos** e, depois, selecione 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.

   A saída do teste mostrará o seguinte: 

   ```
   [
     {
       "id": 1,
       "type": "dog",
       "price": 249.99
     },
     {
       "id": 2,
       "type": "cat",
       "price": 124.99
     },
     {
       "id": 3,
       "type": "fish",
       "price": 0.99
     }
   ]
   ```

   Você transformará esse resultado de acordo com o modelo de mapeamento em  [Transformações de modelo de mapeamento para APIs REST no API Gateway](models-mappings.md).

**Como transformar a resposta de integração `GET`**

1. Selecione a guia **Resposta de integração**.

   Atualmente, não há modelos de mapeamento definidos, portanto, a resposta de integração não será transformada. 

1. Em **Padrão - Resposta**, selecione **Editar**.

1. Selecione **Modelos de mapeamento** e, depois, faça o seguinte:

   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:

      ```
      #set($inputRoot = $input.path('$'))
      [
      #foreach($elem in $inputRoot)
        {
          "description" : "Item $elem.id is a $elem.type.",
          "askingPrice" : $elem.price
        }#if($foreach.hasNext),#end
      
      #end
      ]
      ```

   Escolha **Salvar**.

**Como testar a resposta de integração `GET`**
+ Selecione a guia **Testar** e, depois, **Testar**.

  A saída do teste mostrará a resposta transformada. 

  ```
  [
    {
      "description" : "Item 1 is a dog.",
      "askingPrice" : 249.99
    },
    {
      "description" : "Item 2 is a cat.",
      "askingPrice" : 124.99
    },
    {
      "description" : "Item 3 is a fish.",
      "askingPrice" : 0.99
    }
  ]
  ```

**Como transformar dados de entrada do método `POST`**

1. Selecione o método **POST**.

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

   O modelo CloudFormation preencheu alguns dos campos da solicitação de integração. 
   +  O tipo de integração é AWS service (Serviço da AWS). 
   +  O AWS service (Serviço da AWS) é o DynamoDB. 
   +  O método HTTP é o `POST`. 
   +  A ação é `PutItem`. 
   +  O perfil de execução que possibilita que o API Gateway coloque um item na tabela do DynamoDB é `data-transformation-tutorial-console-APIGatewayRole`. O CloudFormation criou esse perfil para possibilitar que o API Gateway tenha as permissões mínimas para interagir com o DynamoDB. 

    O nome da tabela do DynamoDB não foi especificado. Você especificará o nome nas etapas a seguir. 

1. Em **Passagem do corpo da solicitação**, selecione **Nunca**.

   Isso significa que a API rejeitará dados com tipos de conteúdo que não tenham um modelo de mapeamento.

1. Selecione **Modelos de mapeamento**.

1. O **Tipo de conteúdo** é definido como `application/json`. Isso significa que tipos de conteúdo que não sejam application/json serão rejeitados pela API. Para obter mais informações sobre os comportamentos de passagem direta de integração, consulte . [Comportamento de solicitação de método para cargas úteis sem modelos de mapeamento para APIs REST no API Gateway](integration-passthrough-behaviors.md)

1. Insira o código a seguir no editor de texto.

   ```
   {
       "TableName":"data-transformation-tutorial-console-ddb",
       "Item": {
           "id": {
               "N": $input.json("$.id")
           },
           "type": {
               "S": $input.json("$.type")
           },
           "price": {
               "N": $input.json("$.price")
           }
       }
   }
   ```

    Esse modelo especifica a tabela como `data-transformation-tutorial-console-ddb` e define os itens como `id`, `type` e `price`. Os itens virão do corpo do método `POST`. Você também pode usar um modelo de dados para ajudar a criar um modelo de mapeamento. Para obter mais informações, consulte [Solicitar validação para APIs REST no API Gateway](api-gateway-method-request-validation.md). 

1. Escolha **Salvar** para salvar seu modelo de mapeamento. 

**Como adicionar um método e uma resposta de integração do método `POST`**

O CloudFormation criou um método em branco e uma resposta de integração. Você editará essa resposta para fornecer mais informações. Para ter mais informações sobre como editar respostas, consulte [Exemplos de mapeamento de parâmetros para APIs REST no API Gateway](request-response-data-mappings.md).

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

1. Selecione **Modelos de mapeamento** e, depois, **Adicionar modelo de mapeamento**.

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

1. No editor de código, insira o seguinte modelo de mapeamento de saída para enviar uma mensagem de saída:

   ```
   { "message" : "Your response was recorded at $context.requestTime" }
   ```

   Para ter mais informações sobre variáveis de contexto, consulte [Variáveis de contexto para transformações de dados](api-gateway-mapping-template-reference.md#context-variable-reference).

1. Escolha **Salvar** para salvar seu modelo de mapeamento. 

**Testar o método `POST`**

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

1. No corpo da solicitação, insira o exemplo a seguir.

   ```
   {
             "id": "4",
             "type" : "dog",
             "price": "321"
   }
   ```

1. Escolha **Testar**.

   A saída deve mostrar sua mensagem de êxito.

    Você pode abrir o console do DynamoDB em [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) para verificar se o item de exemplo está na sua tabela. 

**Para excluir uma pilha do CloudFormation**

1. Abra o console do CloudFormation em [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Selecione sua pilha do CloudFormation.

1. Escolha **Excluir** e, em seguida, confirme sua escolha.

## Configurar a transformação de dados usando a CLI da AWS
<a name="mapping-example-cli"></a>

Neste tutorial, você criará uma API incompleta e uma tabela do DynamoDB usando o arquivo .zip [data-transformation-tutorial-console.zip](samples/data-transformation-tutorial-cli.zip) a seguir. Essa API incompleta tem um recurso `/pets` com um método `GET` integrado ao endpoint HTTP `http://petstore-demo-endpoint.execute-api.com/petstore/pets`. Você criará um método `POST` para se conectar a uma tabela do DynamoDB e usará modelos de mapeamento para inserir dados em uma tabela do DynamoDB. 
+ Você transformará os dados de saída de acordo com o modelo de mapeamento em  [Transformações de modelo de mapeamento para APIs REST no API Gateway](models-mappings.md).
+ Você criará um método `POST` para possibilitar que o usuário `POST` informações sobre animais de estimação em uma tabela do Amazon DynamoDB usando um modelo de mapeamento.

**Como criar uma pilha do CloudFormation**

Baixe e descompacte [o modelo de criação de aplicativos para CloudFormation](samples/data-transformation-tutorial-cli.zip). 

Para concluir o tutorial a seguir, é necessária a [AWS Command Line Interface (AWS CLI) versão 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). 

Para comandos longos, um caractere de escape (`\`) é usado para dividir um comando em várias linhas.
**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://learn.microsoft.com/en-us/windows/wsl/install). Os exemplos de comandos da CLI neste guia usam a formatação Linux. Os comandos que incluem documentos JSON em linha deverão ser reformatados se você estiver usando a CLI do Windows. 

1.  Use o comando a seguir para criar a pilha de CloudFormation.

   ```
   aws cloudformation create-stack --stack-name data-transformation-tutorial-cli --template-body file://data-transformation-tutorial-cli.zip --capabilities CAPABILITY_NAMED_IAM 
   ```

1. CloudFormationO fornece os recursos especificados no modelo. Pode demorar alguns minutos para concluir o provisionamento de seus recursos. Use o comando a seguir para ver o status de sua pilha de CloudFormation.

   ```
   aws cloudformation describe-stacks --stack-name data-transformation-tutorial-cli
   ```

1. Quando o status da sua pilha de CloudFormation for `StackStatus: "CREATE_COMPLETE"`, use o comando a seguir para recuperar valores de saída relevantes para etapas futuras.

   ```
    aws cloudformation describe-stacks --stack-name data-transformation-tutorial-cli --query "Stacks[*].Outputs[*].{OutputKey: OutputKey, OutputValue: OutputValue, Description: Description}"
   ```

   Os valores de saída são os seguintes:
   + ApiRole, que é o nome do perfil que possibilita que o API Gateway coloque itens na tabela do DynamoDB. Para este tutorial, o nome do perfil é `data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG`.
   + DDBTableName, que é o nome da tabela do DynamoDB. Para este tutorial, o nome da tabela é `data-transformation-tutorial-cli-ddb`.
   + ResourceId, que é o ID do recurso de animais de estimação em que os métodos `GET` e `POST` são expostos. Para este tutorial, o ID do recurso é `efg456`.
   + ApiId, que é o ID da API. Para este tutorial, o ID da API é `abc123`.

**Como testar o método `GET` antes da transformação de dados**
+ Use o comando a seguir para testar o método `GET`. 

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
            --resource-id efg456 \
            --http-method GET
  ```

  A saída do teste mostrará o seguinte:

  ```
  [
    {
      "id": 1,
      "type": "dog",
      "price": 249.99
    },
    {
      "id": 2,
      "type": "cat",
      "price": 124.99
    },
    {
      "id": 3,
      "type": "fish",
      "price": 0.99
    }
  ]
  ```

  Você transformará esse resultado de acordo com o modelo de mapeamento em  [Transformações de modelo de mapeamento para APIs REST no API Gateway](models-mappings.md).

**Como transformar a resposta de integração `GET`**
+ Use o comando a seguir para atualizar a resposta de integração do método `GET`. Substitua o *rest-api-id* e o *resource-id* pelos seus valores.

  Use o comando a seguir para criar uma resposta de integração.

  ```
  aws apigateway put-integration-response --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method GET \
    --status-code 200 \
    --selection-pattern "" \
    --response-templates '{"application/json": "#set($inputRoot = $input.path(\"$\"))\n[\n#foreach($elem in $inputRoot)\n {\n  \"description\": \"Item $elem.id is a $elem.type\",\n  \"askingPrice\": \"$elem.price\"\n }#if($foreach.hasNext),#end\n\n#end\n]"}'
  ```

**Como testar o método `GET`**
+ Use o comando a seguir para testar o método `GET`.

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method GET \
  ```

  A saída do teste mostrará a resposta transformada. 

  ```
  [
    {
      "description" : "Item 1 is a dog.",
      "askingPrice" : 249.99
    },
    {
      "description" : "Item 2 is a cat.",
      "askingPrice" : 124.99
    },
    {
      "description" : "Item 3 is a fish.",
      "askingPrice" : 0.99
    }
  ]
  ```

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

1. Use o comando a seguir para criar um novo método no recurso `/pets`.

   ```
   aws apigateway put-method --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --authorization-type "NONE" \
   ```

   Esse método possibilitará que você envie informações sobre animais de estimação para a tabela do DynamoDB que você criou na pilha de CloudFormation.

1.  Use o comando a seguir para criar uma integração do AWS service (Serviço da AWS) no método `POST`.

   ```
   aws apigateway put-integration --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --type AWS \
     --integration-http-method POST \
     --uri "arn:aws:apigateway:us-east-2:dynamodb:action/PutItem" \
     --credentials arn:aws:iam::111122223333:role/data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG \
     --request-templates '{"application/json":"{\"TableName\":\"data-transformation-tutorial-cli-ddb\",\"Item\":{\"id\":{\"N\":$input.json(\"$.id\")},\"type\":{\"S\":$input.json(\"$.type\")},\"price\":{\"N\":$input.json(\"$.price\")} }}"}'
   ```

1.  Use o comando a seguir para criar uma resposta de método para uma chamada bem-sucedida do método `POST`. 

   ```
   aws apigateway put-method-response --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --status-code 200
   ```

1. Use o comando a seguir para criar uma resposta de integração para uma chamada bem-sucedida do método `POST`.

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --status-code 200 \
     --selection-pattern "" \
     --response-templates '{"application/json": "{\"message\": \"Your response was recorded at $context.requestTime\"}"}'
   ```

**Como testar o método `POST`**
+ Use o comando a seguir para testar o método `POST`.

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method POST \
    --body '{\"id\": \"4\", \"type\": \"dog\", \"price\": \"321\"}'
  ```

  A saída mostrará a mensagem de êxito.

**Para excluir uma pilha do CloudFormation**
+ Use o comando a seguir para excluir seus recursos de CloudFormation.

  ```
  aws cloudformation delete-stack  --stack-name data-transformation-tutorial-cli
  ```

## Modelo CloudFormation de transformação de dados concluído
<a name="api-gateway-data-transformations-full-cfn-stack"></a>

O exemplo a seguir é um modelo de CloudFormation completo, que cria uma API e uma tabela do DynamoDB com um recurso `/pets` com os métodos `GET` e `POST`. 
+ O método `GET` obterá dados do endpoint HTTP `http://petstore-demo-endpoint.execute-api.com/petstore/pets`. Os dados de saída serão transformados de acordo com o modelo de mapeamento em  [Transformações de modelo de mapeamento para APIs REST no API Gateway](models-mappings.md).
+ O método `POST` possibilitará que o usuário `POST` informações sobre animais de estimação em uma tabela do DynamoDB usando um modelo de mapeamento.

### Exemplo de modelo CloudFormation
<a name="mapping-template-cfn-example"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: A completed Amazon API Gateway REST API that uses non-proxy integration to POST to an Amazon DynamoDB table and non-proxy integration to GET transformed pets data.
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  DynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      TableName: !Sub data-transformation-tutorial-complete
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: N
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
  APIGatewayRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17		 	 	 
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
      Policies:
        - PolicyName: APIGatewayDynamoDBPolicy
          PolicyDocument:
            Version: 2012-10-17		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - 'dynamodb:PutItem'
                Resource: !GetAtt DynamoDBTable.Arn
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: data-transformation-complete-api
      ApiKeySourceType: HEADER
  PetsResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'pets'
  PetsMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: HTTP
        Credentials: !GetAtt APIGatewayRole.Arn
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
        PassthroughBehavior: WHEN_NO_TEMPLATES
        IntegrationResponses:
          - StatusCode: '200'
            ResponseTemplates:
              application/json: "#set($inputRoot = $input.path(\"$\"))\n[\n#foreach($elem in $inputRoot)\n {\n  \"description\": \"Item $elem.id is a $elem.type\",\n  \"askingPrice\": \"$elem.price\"\n }#if($foreach.hasNext),#end\n\n#end\n]"
      MethodResponses:
        - StatusCode: '200'
  PetsMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: POST
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        Credentials: !GetAtt APIGatewayRole.Arn
        IntegrationHttpMethod: POST
        Uri: arn:aws:apigateway:us-west-1:dynamodb:action/PutItem
        PassthroughBehavior: NEVER
        RequestTemplates: 
          application/json: "{\"TableName\":\"data-transformation-tutorial-complete\",\"Item\":{\"id\":{\"N\":$input.json(\"$.id\")},\"type\":{\"S\":$input.json(\"$.type\")},\"price\":{\"N\":$input.json(\"$.price\")} }}"
        IntegrationResponses:
          - StatusCode: 200
            ResponseTemplates:
              application/json: "{\"message\": \"Your response was recorded at $context.requestTime\"}"
      MethodResponses:
        - StatusCode: '200'

  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - PetsMethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
Outputs:
  ApiId:
    Description: API ID for CLI commands
    Value: !Ref Api
  ResourceId:
    Description: /pets resource ID for CLI commands
    Value: !Ref PetsResource
  ApiRole:
    Description: Role ID to allow API Gateway to put and scan items in DynamoDB table
    Value: !Ref APIGatewayRole
  DDBTableName:
    Description: DynamoDB table name
    Value: !Ref DynamoDBTable
```