

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 教學課程：修改 AWS 服務整合的整合請求和回應
<a name="set-up-data-transformations-in-api-gateway"></a>

下列教學課程說明如何使用映射範本轉換來設定映射範本，以使用主控台和 CLI AWS 轉換整合請求和回應。

**Topics**
+ [使用 API Gateway 主控台設定資料轉換](#mapping-example-console)
+ [使用 CLI AWS 設定資料轉換](#mapping-example-cli)
+ [已完成的資料轉換 CloudFormation 範本](#api-gateway-data-transformations-full-cfn-stack)

## 使用 API Gateway 主控台設定資料轉換
<a name="mapping-example-console"></a>

在本教學課程中，您將使用下列 .zip 檔案 [data-transformation-tutorial-console.zip](samples/data-transformation-tutorial-console.zip)，建立不完整的 API 和 DynamoDB 資料表。此不完整的 API 具有 `/pets` 資源，其中含有 `GET` 和 `POST` 方法。
+ `GET` 方法將從 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點取得資料。輸出資料將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md) 中的對應範本進行轉換。
+ `POST` 方法可讓使用者使用對應範本，將寵物資訊 `POST` 至 Amazon DynamoDB 資料表。

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/data-transformation-tutorial-console.zip)。您將使用此範本建立 DynamoDB 資料表，以發布寵物資訊和不完整的 API。您將完成 API Gateway 主控台中的其餘步驟。

**建立 CloudFormation 堆疊**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選擇 **Create stack (建立堆疊)**，然後選擇 **With new resources (standard) (使用新資源 (標準))**。

1. 對於 **Specify template (指定範本)**，選擇 **Upload a template file (上傳範本檔案)**。

1. 選取您下載的範本。

1. 選擇 **Next** (下一步)。

1. 針對 **Stack name (堆疊名稱)**，輸入 **data-transformation-tutorial-console**，然後選擇 **Next (下一步)**。

1. 針對 **Configure stack options (設定堆疊選項)**，選擇 **Next (下一步)**。

1. 針對 **功能**，確認 CloudFormation 可以在您的帳戶中建立 IAM 資源。

1. 選擇**下一步**，然後選擇**提交**。

CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。當您的 CloudFormation 堆疊狀態為 **CREATE\$1COMPLETE** 時，您就可以繼續進行下一個步驟。

**測試 `GET` 整合回應**

1. 在 CloudFormation 堆疊**的資源**索引標籤上**data-transformation-tutorial-console**，選取 API 的實體 ID。

1. 在主導覽窗格中，選擇**資源**，然後選取 **GET** 方法。

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

   測試的輸出將顯示下列內容：

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

   您將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本轉換此輸出。

**轉換 `GET` 整合回應**

1. 選擇**整合回應**索引標籤。

   目前，沒有已定義的對應範本，因此不會轉換整合回應。

1. 針對**預設 - 回應**，選擇**編輯**。

1. 選擇**對應範本**，然後執行下列動作：

   1. 選擇**新增映射範本**。

   1. 針對**內容類型**，輸入 **application/json**。

   1. 針對**範本內文**，輸入下列內容：

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

   選擇**儲存**。

**測試 `GET` 整合回應**
+ 選擇**測試**索引標籤，然後選擇**測試**。

  測試的輸出將顯示轉換後的回應。

  ```
  [
    {
      "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
    }
  ]
  ```

**從 `POST` 方法轉換輸入資料**

1. 選擇 **POST** 方法。

1. 選擇**整合請求**索引標籤，然後針對**整合請求設定**，選擇**編輯**。

    CloudFormation 範本已填入一些整合請求欄位。
   +  整合類型為 AWS 服務。
   +  AWS 服務 是 DynamoDB。
   +  HTTP 方法為 `POST`。
   +  動作為 `PutItem`。
   +  允許 API Gateway 將項目放入 DynamoDB 資料表的執行角色是 `data-transformation-tutorial-console-APIGatewayRole`. CloudFormation created this role，以允許 API Gateway 具有與 DynamoDB 互動的最低許可。

    尚未指定 DynamoDB 資料表的名稱。您將在下列步驟中指定此名稱。

1. 針對**請求內文傳遞**，選取**永不**。

   這意味著 API 將拒絕 Content-Type 沒有對應範本的資料。

1. 選擇**對應範本**。

1. **內容類型**會設定為 `application/json`。這表示不是 application/json 的內容類型將遭 API 拒絕。如需整合傳遞行為的詳細資訊，請參閱 [API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

1. 將下列程式碼輸入至文字編輯器。

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

    此範本會將資料表指定為 `data-transformation-tutorial-console-ddb`，並將項目設為 `id`、`type` 和 `price`。這些項目將來自 `POST` 方法的內文。您也可以使用資料模型來協助建立對應範本。如需詳細資訊，請參閱[API Gateway 中的 REST API 的請求驗證](api-gateway-method-request-validation.md)。

1. 選擇**儲存**以儲存您的映射範本。

**從 `POST` 方法新增方法和整合回應**

 CloudFormation 已建立空白方法和整合回應。您將編輯此回應，以提供詳細資訊。如需如何編輯回應的詳細資訊，請參閱 [API Gateway 中 REST API 的參數映射範例](request-response-data-mappings.md)。

1. 在**整合回應**索引標籤上，針對**預設 - 回應**選擇**編輯**。

1. 選擇**對應範本**，然後選擇**新增對應範本**。

1. 針對 **Content-Type**，輸入 **application/json**。

1. 在程式碼編輯器中，輸入下列輸出對應範本以傳送輸出訊息：

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

   如需內容變數的詳細資訊，請參閱 [資料轉換的內容變數](api-gateway-mapping-template-reference.md#context-variable-reference)。

1. 選擇**儲存**以儲存您的對應範本。

**測試 `POST` 方法**

選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 在請求內文中，輸入下列範例。

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

1. 選擇**測試**。

   輸出應該會顯示您的成功訊息。

    您可以在 [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) 開啟 DynamoDB 主控台，以驗證範例項目是否位於您的資料表中。

**刪除 CloudFormation 堆疊**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選取您的 CloudFormation 堆疊。

1. 選擇**刪除**，然後確認您的選擇。

## 使用 CLI AWS 設定資料轉換
<a name="mapping-example-cli"></a>

在本教學課程中，您將使用下列 .zip 檔案 [data-transformation-tutorial-cli.zip](samples/data-transformation-tutorial-cli.zip)，建立不完整的 API 和 DynamoDB 資料表。這個不完整的 API 具有 `/pets` 資源，其中含有與 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點整合的 `GET` 方法。您將建立 `POST` 方法，以連線至 DynamoDB 資料表，並使用對應範本將資料輸入至 DynamoDB 資料表。
+ 您將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本轉換輸出資料。
+ 您將建立 `POST` 方法，允許使用者使用對應範本，將寵物資訊 `POST` 至 Amazon DynamoDB 資料表。

**建立 CloudFormation 堆疊**

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/data-transformation-tutorial-cli.zip)。

若要完成下列教學課程，您需要 [AWS Command Line Interface (AWS CLI) 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

對於長命令，逸出字元 (`\`) 用於將命令分割為多行。
**注意**  
在 Windows 中，作業系統的內建終端機不支援您常用的某些 Bash CLI 命令 (例如 `zip`)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本，請[安裝適用於 Linux 的 Windows 子系統](https://learn.microsoft.com/en-us/windows/wsl/install)。本指南中的 CLI 命令範例使用 Linux 格式。如果您使用的是 Windows CLI，必須重新格式化包含內嵌 JSON 文件的命令。

1.  使用下列命令來建立 CloudFormation 堆疊。

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

1. CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。使用下列命令來查看 CloudFormation 堆疊的狀態。

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

1. 當您的 CloudFormation 堆疊狀態為 時`StackStatus: "CREATE_COMPLETE"`，請使用下列命令來擷取未來步驟的相關輸出值。

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

   輸出值如下：
   + ApiRole，這是允許 API Gateway 將項目放入 DynamoDB 資料表的角色名稱。對於本教學課程，角色名稱為 `data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG`。
   + DDBTableName，這是 DynamoDB 資料表的名稱。對於本教學課程，資料表名稱為 `data-transformation-tutorial-cli-ddb`。
   + ResourceId，這是 `GET` 和 `POST` 方法公開所在寵物資源的 ID。對於本教學課程，資源 ID 為 `efg456`
   + ApiId，這是 API 的 ID。對於本教學課程，API ID 為 `abc123`。

**在資料轉換之前測試 `GET` 方法**
+ 使用下列命令測試 `GET` 方法。

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

  測試的輸出將顯示下列內容。

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

  您將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本轉換此輸出。

**轉換 `GET` 整合回應**
+ 使用下列命令更新 `GET` 方法的整合回應。將 *rest-api-id* 和 *resource-id* 取代為您的值。

  使用下列命令建立整合回應。

  ```
  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]"}'
  ```

**測試 `GET` 方法**
+ 使用下列命令測試 `GET` 方法。

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

  測試的輸出將顯示轉換後的回應。

  ```
  [
    {
      "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
    }
  ]
  ```

**建立 `POST` 方法**

1. 使用下列命令，在 `/pets` 資源上建立新方法。

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

   此方法可讓您將寵物資訊傳送至您在 CloudFormation 堆疊中建立的 DynamoDB 資料表。

1.  使用下列命令在 `POST`方法上建立 AWS 服務 整合。

   ```
   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.  使用下列命令，為 `POST` 方法的成功呼叫建立方法回應。

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

1. 使用下列命令，為 `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\"}"}'
   ```

**測試 `POST` 方法**
+ 使用下列命令測試 `POST` 方法。

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

  輸出將顯示成功訊息。

**刪除 CloudFormation 堆疊**
+ 使用下列命令來刪除您的 CloudFormation 資源。

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

## 已完成的資料轉換 CloudFormation 範本
<a name="api-gateway-data-transformations-full-cfn-stack"></a>

下列範例是已完成的 CloudFormation 範本，其會使用 和 `POST`方法建立具有 `/pets` 資源的 API `GET`和 DynamoDB 資料表。
+ `GET` 方法將從 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點取得資料。輸出資料將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本進行轉換。
+ `POST` 方法可讓使用者使用對應範本，將寵物資訊 `POST` 至 DynamoDB 資料表。

### 範本範例 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
```