

# API Gateway での REST API のテンプレート変換のマッピング
<a name="models-mappings"></a>

マッピングテンプレート変換では、統合リクエストまたは統合レスポンスの変更にマッピングテンプレートを使用します。*マッピングテンプレート*は、[Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) で表現されるスクリプトであり、`Content-type` ヘッダーに基づいて [JSONPath](https://goessner.net/articles/JsonPath/) を使用してペイロードに適用されます。マッピングテンプレート変換を使用する場合は、マッピングテンプレートを使います。このセクションでは、マッピングテンプレートに関連する概念的な情報を説明します。

次の図は、PetStore 統合エンドポイントと統合されている `POST /pets` リソースのリクエストライフサイクルを説明しています。この API では、ユーザーはペットに関するデータを送信し、統合エンドポイントはペットの譲渡料金を返します。このリクエストライフサイクルでは、マッピングテンプレート変換が、リクエスト本文を統合エンドポイントにフィルタリングして、統合エンドポイントからレスポンス本文をフィルタリングします。

![\[リクエストライフサイクルの例\]](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/mapping-template-transforms.png)


以下のセクションでは、リクエストレスポンスのライフサイクルについて説明します。

## メソッドリクエストと統合リクエスト
<a name="models-mappings-request"></a>

前の例で、これがメソッドリクエストに送信されたリクエスト本文である場合:

```
POST /pets
    HTTP/1.1
    Host:abcd1234.us-west-2.amazonaws.com
    Content-type: application/json
    
  {
    "id": 1,
    "type": "dog",
    "Age": 11,
  }
```

このリクエスト本文は、統合エンドポイントで使用される適切な形式ではないため、API Gateway はマッピングテンプレート変換を実行します。API Gateway は、Content-Type `application/json` 用に定義されたマッピングテンプレートがあるため、マッピングテンプレート変換のみを実行します。Content-Type のマッピングテンプレートを定義しない場合、デフォルトでは、API Gateway は統合リクエストを介して統合エンドポイントに本文を渡します。この動作を変更するには、「[API Gateway で REST API のマッピングテンプレートを使用しないペイロードのメソッドリクエストの動作](integration-passthrough-behaviors.md)」を参照してください。

次のマッピングテンプレートは、統合エンドポイントに送信される前に、統合リクエストのメソッドリクエストデータを変換します。

```
#set($inputRoot = $input.path('$'))
  {
    "dogId" : "dog_"$elem.id,
    "Age": $inputRoot.Age
  }
```

1. `$inputRoot` 変数は、前のセクションにおける元の JSON データのルートオブジェクトです。ディレクティブは `#` 記号で始まります。

1. `dog` は、ユーザーの `id` と文字列値を連結したものです。

1. `Age` はメソッドリクエスト本文からのものです。

次に、以下の出力が統合エンドポイントに転送されます。

```
{
    "dogId" : "dog_1",
    "Age": 11
  }
```

## 統合レスポンスとメソッドレスポンス
<a name="models-mappings-response"></a>

統合エンドポイントへのリクエストが正常に完了すると、エンドポイントは API Gateway の統合レスポンスにレスポンスを送信します。以下は、統合エンドポイントからの出力データの例です。

```
{
    "dogId" : "dog_1",
    "adoptionFee": 19.95,
}
```

メソッドレスポンスは、統合レスポンスが返すペイロードとは異なるペイロードを想定しています。API Gateway はマッピングテンプレート変換を実行します。API Gateway は、Content-Type `application/json` 用に定義されたマッピングテンプレートがあるため、マッピングテンプレート変換のみを実行します。Content-Type のマッピングテンプレートを定義しない場合、デフォルトでは、API Gateway は統合レスポンスを介してメソッドレスポンスに本文を渡します。この動作を変更するには、「[API Gateway で REST API のマッピングテンプレートを使用しないペイロードのメソッドリクエストの動作](integration-passthrough-behaviors.md)」を参照してください。

```
#set($inputRoot = $input.path('$'))
  {
    "adoptionFee" : $inputRoot.adoptionFee,
  }
```

以下の出力は、メソッドレスポンスに送信されます。

```
{"adoptionFee": 19.95}
```

これで、マッピングテンプレート変換の例は完了です。可能であれば、データの変換には、マッピングテンプレート変換を使用する代わりに、プロキシ統合を使用することをお勧めします。詳細については、「[API Gateway API 統合タイプの選択](api-gateway-api-integration-types.md)」を参照してください。

# API Gateway で REST API のマッピングテンプレートを使用しないペイロードのメソッドリクエストの動作
<a name="integration-passthrough-behaviors"></a>

メソッドリクエストにペイロードがあり、`Content-Type` ヘッダーにマッピングテンプレートが定義されていない場合は、クライアントが提供するリクエストペイロードを変換せずに統合リクエストを介してバックエンドに渡すことができます。このプロセスは統合パススルーと呼ばれます。

 受信リクエストの実際のパススルー動作は、この設定によって決まります。3 つのオプションがあります。

**リクエストした Content-Type ヘッダーと一致するテンプレートがない場合**  
メソッドリクエストのコンテンツタイプが、マッピングテンプレートと関連付けられたコンテンツタイプに一致しない場合に、統合リクエストをパススルーしてメソッドリクエスト本文を変換せずにバックエンドに渡す場合は、このオプションを選択します。  
API Gateway API を呼び出すときは、[[統合]](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) の `passthroughBehavior` プロパティの値として `WHEN_NO_MATCH` を設定して、このオプションを選択します。

**テンプレートが定義されていない場合 (推奨)**  
統合リクエストでマッピングテンプレートが定義されていないときに、統合リクエストをパススルーしてメソッドリクエスト本文を変換せずにバックエンドに渡す場合は、このオプションを選択します。このオプションを選択した際にテンプレートが定義されている場合、定義されたマッピングテンプレートのいずれにも一致しないペイロードとコンテンツタイプのメソッドリクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。  
API Gateway API を呼び出すときは、[[統合]](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) の `passthroughBehavior` プロパティの値として `WHEN_NO_TEMPLATES` を設定して、このオプションを選択します。

**なし**  
統合リクエストでマッピングテンプレートが定義されていないときに、統合リクエストをパススルーしてメソッドリクエストボディを変換せずにバックエンドに渡さない場合は、このオプションを選択します。このオプションを選択したときにテンプレートが定義されている場合、マッピングされていないコンテンツタイプのメソッドリクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。  
API Gateway API を呼び出すときは、[[統合]](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) の `passthroughBehavior` プロパティの値として `NEVER` を設定して、このオプションを選択します。

 次の例では、可能なパススルー動作について説明します。

例 1: `application/json` コンテンツタイプで 1 つのマッピングテンプレートが統合リクエストで定義されている。


| Content-type | パススルーのオプション | 行動 | 
| --- | --- | --- | 
| なし API Gateway のデフォルトは `application/json` | WHEN\$1NO\$1MATCH | リクエストペイロードはテンプレートを使用して変換されます。 | 
| なし API Gateway のデフォルトは `application/json` | WHEN\$1NO\$1TEMPLATES | リクエストペイロードはテンプレートを使用して変換されます。 | 
| なし API Gateway のデフォルトは `application/json` | NEVER | リクエストペイロードはテンプレートを使用して変換されます。 | 
| application/json | WHEN\$1NO\$1MATCH | リクエストペイロードはテンプレートを使用して変換されます。 | 
| application/json | WHEN\$1NO\$1TEMPLATES | リクエストペイロードはテンプレートを使用して変換されます。 | 
| application/json | NEVER | リクエストペイロードはテンプレートを使用して変換されます。 | 
| application/xml | WHEN\$1NO\$1MATCH | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| application/xml | WHEN\$1NO\$1TEMPLATES | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| application/xml | NEVER | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 

例 2: `application/xml` コンテンツタイプで 1 つのマッピングテンプレートが統合リクエストで定義されている。


| Content-type | パススルーのオプション | 行動 | 
| --- | --- | --- | 
| なし API Gateway のデフォルトは `application/json` | WHEN\$1NO\$1MATCH | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| なし API Gateway のデフォルトは `application/json` | WHEN\$1NO\$1TEMPLATES | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| なし API Gateway のデフォルトは `application/json` | NEVER | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| application/json | WHEN\$1NO\$1MATCH | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| application/json | WHEN\$1NO\$1TEMPLATES | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| application/json | NEVER | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| application/xml | WHEN\$1NO\$1MATCH | リクエストペイロードはテンプレートを使用して変換されます。 | 
| application/xml | WHEN\$1NO\$1TEMPLATES | リクエストペイロードはテンプレートを使用して変換されます。 | 
| application/xml | NEVER | リクエストペイロードはテンプレートを使用して変換されます。 | 

例 3: 統合リクエストで定義されているマッピングテンプレートがない


| Content-type | パススルーのオプション | 行動 | 
| --- | --- | --- | 
| なし API Gateway のデフォルトは `application/json` | WHEN\$1NO\$1MATCH | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| なし API Gateway のデフォルトは `application/json` | WHEN\$1NO\$1TEMPLATES | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| なし API Gateway のデフォルトは `application/json` | NEVER | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| application/json | WHEN\$1NO\$1MATCH | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| application/json | WHEN\$1NO\$1TEMPLATES | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| application/json | NEVER | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 
| application/xml | WHEN\$1NO\$1MATCH | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| application/xml | WHEN\$1NO\$1TEMPLATES | リクエストペイロードは変換されず、そのままバックエンドに送信されます。 | 
| application/xml | NEVER | リクエストは、HTTP 415 Unsupported Media Type レスポンスで拒否されます。 | 

# 追加の API Gateway での REST API マッピングテンプレート例
<a name="example-photos"></a>

次の例は、マッピングテンプレートを使用して統合リクエストと統合レスポンスデータを変換する API Gateway のフォトアルバム API を説明しています。この例では、データモデルを使用して、メソッドリクエストと統合レスポンスのペイロードも定義しています。データモデルの詳細については、「[REST API のデータモデル](models-mappings-models.md)」を参照してください。

## メソッドリクエストと統合リクエスト
<a name="example-photos-request"></a>

以下は、メソッドリクエスト本文を定義するモデルです。この入力モデルでは、発信者が 1 ページの写真をアップロードする必要があり、ページごとに最低 10 枚の写真が必要です。この入力モデルを使用して SDK を生成したり、API のリクエストの検証に使用したりできます。リクエストの検証の使用中に、メソッドリクエスト本文がモデルのデータ構造に準拠していない場合、API Gateway はリクエストを失敗にします。

```
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PhotosInputModel",
  "type": "object",
  "properties": {
    "photos": {
      "type": "object",
      "required" : [
      "photo"
      ],
      "properties": {
        "page": { "type": "integer" },
        "pages": { "type": "string" },
        "perpage": { "type": "integer", "minimum" : 10 },
        "total": { "type": "string" },
        "photo": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "owner": { "type": "string" },
              "photographer_first_name" : {"type" : "string"},
              "photographer_last_name" : {"type" : "string"},
              "secret": { "type": "string" },
              "server": { "type": "string" },
              "farm": { "type": "integer" },
              "title": { "type": "string" },
              "ispublic": { "type": "boolean" },
              "isfriend": { "type": "boolean" },
              "isfamily": { "type": "boolean" }
            }
          }
        }
      }
    }
  }
}
```

以下は、上記のデータモデルのデータ構造に準拠するメソッドリクエスト本文の例です。

```
{
  "photos": {
    "page": 1,
    "pages": "1234",
    "perpage": 100,
    "total": "123398",
    "photo": [
      {
        "id": "12345678901",
        "owner": "23456789@A12",
        "photographer_first_name" : "Saanvi",
        "photographer_last_name" : "Sarkar",
        "secret": "abc123d456",
        "server": "1234",
        "farm": 1,
        "title": "Sample photo 1",
        "ispublic": true,
        "isfriend": false,
        "isfamily": false
      },
      {
        "id": "23456789012",
        "owner": "34567890@B23",
        "photographer_first_name" : "Richard",
        "photographer_last_name" : "Roe",
        "secret": "bcd234e567",
        "server": "2345",
        "farm": 2,
        "title": "Sample photo 2",
        "ispublic": true,
        "isfriend": false,
        "isfamily": false
      }
    ]
  }
}
```

この例では、クライアントが上記のメソッドリクエスト本文を送信すると、このマッピングテンプレートは統合エンドポイントに必要な形式と一致するようにペイロードを変換します。

```
#set($inputRoot = $input.path('$'))
{
  "photos": [
#foreach($elem in $inputRoot.photos.photo)
    {
      "id": "$elem.id",
      "photographedBy": "$elem.photographer_first_name $elem.photographer_last_name",
      "title": "$elem.title",
      "ispublic": $elem.ispublic,
      "isfriend": $elem.isfriend,
      "isfamily": $elem.isfamily
    }#if($foreach.hasNext),#end
		
#end
  ]
}
```

次の例は、変換からの出力データです。

```
{
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    }		
  ]
}
```

このデータは統合リクエストに送信されてから、統合エンドポイントに送信されます。

## 統合レスポンスとメソッドレスポンス
<a name="photos-example-response"></a>

以下は、統合エンドポイントからの写真データの出力モデルの例です。このモデルはメソッドレスポンスモデルに使用できます。これは、API 用に厳密に型指定した SDK を生成するときに必要です。これにより、出力が Java や Objective-C の適切なクラスにキャストされます。

```
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PhotosOutputModel",
  "type": "object",
  "properties": {
    "photos": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "photographedBy": { "type": "string" },
          "title": { "type": "string" },
          "ispublic": { "type": "boolean" },
          "isfriend": { "type": "boolean" },
          "isfamily": { "type": "boolean" }
        }
      }
    }
  }
}
```

統合エンドポイントは、このモデルのデータ構造に準拠するレスポンスで応答しない場合があります。例えば、統合レスポンスは次のようになります。

```
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "description": "My sample photo 1",
      "public": true,
      "friend": false,
      "family": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "description": "My sample photo 1",
      "public": true,
      "friend": false,
      "family": false
    }		
  ]
}
```

次のマッピングテンプレートの例では、統合レスポンスデータをメソッドレスポンスで想定される形式に変換します。

```
#set($inputRoot = $input.path('$'))
{
  "photos": [
#foreach($elem in $inputRoot.photos.photo)
    {
      "id": "$elem.id",
      "photographedBy": "$elem.photographer_first_name $elem.photographer_last_name",
      "title": "$elem.title",
      "ispublic": $elem.public,
      "isfriend": $elem.friend,
      "isfamily": $elem.family
    }#if($foreach.hasNext),#end
		
#end
  ]
}
```

次の例は、変換からの出力データです。

```
{
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    }		
  ]
}
```

このデータはメソッドレスポンスに送信されてから、クライアントに送信されます。

# API Gateway で REST API の API リクエストパラメータおよびレスポンスパラメータとステータスコードを上書きする
<a name="apigateway-override-request-response-parameters"></a>

マッピングテンプレート変換を使用して、任意のタイプのリクエストパラメータ、レスポンスヘッダー、またはレスポンスステータスコードを上書きできます。マッピングテンプレートを使用して、以下を実行できます。
+ 多対 1 のパラメータマッピングを実行する
+ 標準 API Gateway マッピングが適用された適用された後にパラメータをオーバーライドする
+ 本文の内容やその他のパラメータ値に基づいて条件付きでパラメータをマッピングする
+ プログラムで新しいパラメータを作成する
+ 統合エンドポイントから返されたステータスコードをオーバーライドする

オーバーライドは最終的なものです。オーバーライドは各パラメータに一度だけ適用できます。同じパラメータを複数回オーバーライドしようとすると、API Gateway から `5XX` レスポンスが返されます。テンプレート全体で同じパラメータを複数回オーバーライドする必要がある場合は、変数を作成してテンプレートの終了時にオーバーライドを適用することをお勧めします。テンプレートはテンプレート全体が解析された後にのみ適用されます。

## 例 1: 統合本文に基づいてステータスコードを上書きする
<a name="apigateway-override-request-response-examples"></a>

次の例では、[サンプル API](api-gateway-create-api-from-example.md) を使用して、統合レスポンス本文に基づいてステータスコードを上書きします。

------
#### [ AWS マネジメントコンソール ]

**統合レスポンス本文に基づいてステータスコードを上書きするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. [**API の作成**] を選択します。

1. **[REST API]** では、**[構築]** を選択します。

1. **[API の詳細]** では、**[API の例]** を選択します。

1. **[API の作成]** を選択します。

   API Gateway は、サンプルのペットストア API を作成します。ペットに関する情報を取得するには、`GET /pets/{petId}` の API メソッドリクエストを使用します。ここで、`{petId}` は、ペットの ID 番号に対応するパスパラメータです。

   この例では、エラー状態が検出された場合、`GET` メソッドのレスポンスコードを `400` に上書きします。

1. **[リソース]** ツリーで、`/{petId}` の下の `GET` メソッドを選択します。

1. まず、API の現在の実装をテストします。

   **[テスト]** タブを選択します。タブを表示するには、右矢印ボタンを選択する必要がある場合があります。

1. **[petId]** に「**-1**」と入力し、**[テスト]** を選択します。

   **[レスポンス本文]** は、次のとおりの範囲外エラーを示します。

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   さらに、**[ログ]** の最後の行は `Method completed with status: 200` で終わります。

   統合は正常に完了しましたが、エラーが発生しました。次に、統合本文に基づいてステータスコードを上書きします。

1. **[統合レスポンス]** タブの **[デフォルト - レスポンス]** で、**[編集]** を選択します。

1. **[マッピングテンプレート]** を選択します。

1. [**マッピングテンプレートの追加**] を選択します。

1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

1. **[テンプレート本文]** で次のように入力します。

   ```
   #set($inputRoot = $input.path('$'))
   $input.json("$")
   #if($inputRoot.toString().contains("error"))
   #set($context.responseOverride.status = 400)
   #end
   ```

   このマッピングテンプレートは、統合レスポンスに `error` 文字列が含まれている場合、`$context.responseOverride.status` 変数を使用してステータスコードを `400` に上書きします。

1. **[保存]** を選択します。

1. **[テスト]** タブを選択します。

1. **[petId]** に「**-1**」と入力します。

1. 結果として、[**Response Body (レスポンス本文)**] は範囲外エラーを示します。

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   ただし、**[ログ]** の最後の行は、`Method completed with status: 400` で終わるようになりました。

------
#### [ CloudFormation ]

 この例では、[body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) プロパティを使用して、OpenAPI 定義ファイルを API Gateway にインポートします。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 1
          description: Example pet store API.
          version: "2025-01-14T00:13:18Z"
        paths:
          /pets/{petId}:
            get:
              parameters:
                - name: petId
                  in: path
                  required: true
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}
                responses:
                  default:
                    statusCode: "200"
                    responseTemplates:
                      application/json: |-
                        #set($inputRoot = $input.path('$'))
                        $input.json("$")
                        #if($inputRoot.toString().contains("error"))
                        #set($context.responseOverride.status = 400)
                        #end
                requestParameters:
                  integration.request.path.petId: method.request.path.petId
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

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

次の OpenAPI 定義は、`GET pets/{petId}` リソースを作成して、統合本文に基づいてステータスコードを上書きします。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 1",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:13:18Z"
  },
  "paths" : {
    "/pets/{petId}" : {
      "get" : {
        "parameters" : [ {
          "name" : "petId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}",
          "responses" : {
            "default" : {
              "statusCode" : "200",
              "responseTemplates" : {
                "application/json" : "#set($inputRoot = $input.path('$'))\n$input.json(\"$\")\n#if($inputRoot.toString().contains(\"error\"))\n#set($context.responseOverride.status = 400)\n#end"
              }
            }
          },
          "requestParameters" : {
            "integration.request.path.petId" : "method.request.path.petId"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "Pet" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string"
          },
          "price" : {
            "type" : "number"
          }
        }
      }
    }
  }
}
```

------

## 例 2: リクエストヘッダーを上書きして新しいヘッダーを作成する
<a name="apigateway-override-request-response-examples-2"></a>

次の例では、[サンプル API](api-gateway-create-api-from-example.md) を使用してリクエストヘッダーを上書きして、新しいヘッダーを作成します。

------
#### [ AWS マネジメントコンソール ]

**新しいヘッダーを作成してメソッドのリクエストヘッダーを上書きするには**

1. [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway) で API Gateway コンソールにサインインします。

1. 前のチュートリアルで作成した API の例を選択します。API の名前は **[PetStore]** であるはずです。

1. **[リソース]** ツリーで、`/pet` の下の `GET` メソッドを選択します。

1. **[メソッドリクエスト]** タブの **[メソッドリクエストの設定]** で、**[編集]** を選択します。

1. **[HTTP リクエストヘッダー]** を選択した後、**[ヘッダーの追加]** を選択します。

1. **[Name]** (名前) には **header1** を入力します。

1. **[ヘッダーを追加]** を選択し、**header2** という名前の 2 つ目のヘッダーを作成します。

1. **[保存]** を選択します。

   次に、マッピングテンプレートを使用して、これらのヘッダーを単一のヘッダー値に結合します。

1. **[統合リクエスト]** タブの **[統合リクエストの設定]** で、**[編集]** を選択します。

1. **[リクエスト本文のパススルー]** で、**[テンプレートが定義されていない場合 (推奨)]** を選択します。

1. **[マッピングテンプレート]** を選択し、次の操作を行います。

   1. [**マッピングテンプレートの追加**] を選択します。

   1. **[コンテンツタイプ]** に、「**application/json**」と入力します。

   1. **[テンプレート本文]** で次のように入力します。

      ```
      #set($header1Override = "pets")
      #set($header3Value = "$input.params('header1')$input.params('header2')")
      $input.json("$")
      #set($context.requestOverride.header.header3 = $header3Value)
      #set($context.requestOverride.header.header1 = $header1Override)
      #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
      ```

      このマッピングテンプレートは、`header1` を文字列 `pets` で上書きし、`header1` と `header2` を組み合わせた `$header3Value` という名前の複数値ヘッダーを作成します。

1. **[保存]** を選択します。

1. **[テスト]** タブを選択します。

1. **[ヘッダー]** で、次のコードをコピーします。

   ```
   header1:header1Val
   header2:header2Val
   ```

1. [**Test (テスト)**] を選択します。

   **[ログ]** には次のとおり、このテキストを含むエントリが表示されるはずです。

   ```
   Endpoint request headers: {header3=header1Valheader2Val, 
   header2=header2Val, header1=pets, x-amzn-apigateway-api-id=api-id,
   Accept=application/json, multivalueheader=pets,header1Valheader2Val}
   ```

------
#### [ CloudFormation ]

 この例では、[body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) プロパティを使用して、OpenAPI 定義ファイルを API Gateway にインポートします。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 2
          description: Example pet store API.
          version: "2025-01-14T00:36:18Z"
        paths:
          /pets:
            get:
              parameters:
                - name: header2
                  in: header
                  schema:
                    type: string
                - name: page
                  in: query
                  schema:
                    type: string
                - name: type
                  in: query
                  schema:
                    type: string
                - name: header1
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.header1: method.request.header.header1
                  integration.request.header.header2: method.request.header.header2
                  integration.request.querystring.page: method.request.querystring.page
                  integration.request.querystring.type: method.request.querystring.type
                requestTemplates:
                  application/json: |-
                    #set($header1Override = "pets")
                    #set($header3Value = "$input.params('header1')$input.params('header2')")
                    $input.json("$")
                    #set($context.requestOverride.header.header3 = $header3Value)
                    #set($context.requestOverride.header.header1 = $header1Override)
                    #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

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

 次の OpenAPI 定義は、リソース `GET pets` を作成し、リクエストヘッダーを上書きして新しいヘッダーを作成します。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 2",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:36:18Z"
  },
  "paths" : {
    "/pets" : {
      "get" : {
        "parameters" : [ {
          "name" : "header2",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "page",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "type",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "header1",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.header1" : "method.request.header.header1",
            "integration.request.header.header2" : "method.request.header.header2",
            "integration.request.querystring.page" : "method.request.querystring.page",
            "integration.request.querystring.type" : "method.request.querystring.type"
          },
          "requestTemplates" : {
            "application/json" : "#set($header1Override = \"pets\")\n#set($header3Value = \"$input.params('header1')$input.params('header2')\")\n$input.json(\"$\")\n#set($context.requestOverride.header.header3 = $header3Value)\n#set($context.requestOverride.header.header1 = $header1Override)\n#set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  }
}
```

------

マッピングテンプレートの上書きを使用するには、マッピングテンプレートで以下の `$context` 変数のいずれかを使用します。`$context` 変数のリストについては、「[データ変換のコンテキスト変数](api-gateway-mapping-template-reference.md#context-variable-reference)」を参照してください。

# チュートリアル: AWS サービスへの統合のための統合リクエストとレスポンスを変更する
<a name="set-up-data-transformations-in-api-gateway"></a>

次のチュートリアルでは、マッピングテンプレート変換を使用して、コンソールと AWS CLI で統合リクエストとレスポンスを変換するためのマッピングテンプレートを設定する方法を説明します。

**Topics**
+ [

## API Gateway コンソールを使用してデータ変換を設定する
](#mapping-example-console)
+ [

## AWS CLI を使用してデータ変換を設定する
](#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 には、`GET` メソッドと `POST` メソッドを持つ `/pets` リソースがあります。
+ `GET` メソッドは `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP エンドポイントからデータを取得します。出力データは、[API Gateway での REST API のテンプレート変換のマッピング](models-mappings.md) のマッピングテンプレートに従って変換されます。
+ `POST` メソッドを使用すると、ユーザーはマッピングテンプレートを使用して Amazon DynamoDB テーブルにペット情報を `POST` できます。

[CloudFormation のアプリケーション作成テンプレート](samples/data-transformation-tutorial-console.zip)をダウンロードして解凍します。このテンプレートを使用して、ペット情報と不完全な API を投稿するための DynamoDB テーブルを作成します。残りのステップは API Gateway コンソールで完了します。

**CloudFormation スタックを作成するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. [**スタックの作成**] を選択し、[**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. [**Capabilities**] (機能) で、CloudFormation がアカウントに IAM リソースを作成できることを承認します。

1. **[次へ]** を選択し、**[送信]** を選択します。

CloudFormation は、テンプレートで指定されたリソースをプロビジョニングします。リソースのプロビジョニングには数分かかることがあります。CloudFormation スタックのステータスが **CREATE\$1COMPLETE** の場合は、次のステップに進む準備ができています。

**`GET` 統合レスポンスをテストするには**

1. **data-transformation-tutorial-console** の CloudFormation スタックの **[リソース]** タブで、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 は、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. **[コンテンツタイプ]** に「**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. **[テスト]** を選択します。

   出力に成功メッセージが表示されるはずです。

    DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開いて、サンプル項目がテーブルにあることを確認できます。

**CloudFormation スタックを削除するには**

1. CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. CloudFormation スタックを選択します。

1. [**Delete**] (削除) を選択し、選択を確定します。

## AWS CLI を使用してデータ変換を設定する
<a name="mapping-example-cli"></a>

このチュートリアルでは、.zip ファイル ([data-transformation-tutorial-cli.zip](samples/data-transformation-tutorial-cli.zip)\$1 を使用して不完全な API と DynamoDB テーブルを作成します。この不完全な API には、`http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP エンドポイントと統合された `GET` メソッドを持つ `/pets` リソースがあります。`POST` メソッドを作成して DynamoDB テーブルに接続し、マッピングテンプレートを使用して DynamoDB テーブルにデータを入力します。
+ 出力データは、[API Gateway での REST API のテンプレート変換のマッピング](models-mappings.md) のマッピングテンプレートに従って変換します。
+ `POST` メソッドを作成し、ユーザーがマッピングテンプレートを使用して Amazon DynamoDB テーブルにペット情報を `POST` できるようにします。

**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 統合バージョンを取得するには、[Windows Subsystem for Linux をインストール](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 テンプレートです。これにより、API と、`GET` メソッドと `POST` メソッドを持つ `/pets` リソースを作成します。
+ `GET` メソッドは、`http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP エンドポイントからデータを取得します。出力データは、[API Gateway での REST API のテンプレート変換のマッピング](models-mappings.md) のマッピングテンプレートに従って変換されます。
+ `POST` メソッドを使用すると、ユーザーはマッピングテンプレートを使用して DynamoDB テーブルにペット情報を `POST` できます。

### 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
```

# API Gateway のテンプレート変換のマッピングに変数を使用する例
<a name="api-gateway-mapping-variable-examples"></a>

以下の例は、マッピングテンプレートで `$context` 変数、`input` 変数、`util` 変数を使用する方法を説明しています。入力イベントを API Gateway に返すモック統合または Lambda 非プロキシ統合を使用できます。サポートされているデータ変換のすべての変数のリストについては、「[API Gateway のデータ変換の変数](api-gateway-mapping-template-reference.md)」を参照してください。

## 例 1: 統合エンドポイントに複数の `$context` 変数を渡す
<a name="context-variables-template-example"></a>

次の例は、統合リクエストペイロード内で、受信 `$context` 変数をわずかに異なる名前のバックエンド変数にマッピングするマッピングテンプレートを示しています。

```
{
    "stage" : "$context.stage",
    "request_id" : "$context.requestId",
    "api_id" : "$context.apiId",
    "resource_path" : "$context.resourcePath",
    "resource_id" : "$context.resourceId",
    "http_method" : "$context.httpMethod",
    "source_ip" : "$context.identity.sourceIp",
    "user-agent" : "$context.identity.userAgent",
    "account_id" : "$context.identity.accountId",
    "api_key" : "$context.identity.apiKey",
    "caller" : "$context.identity.caller",
    "user" : "$context.identity.user",
    "user_arn" : "$context.identity.userArn"
}
```

このマッピングテンプレートの出力は、次のようになります。

```
{
  stage: 'prod',
  request_id: 'abcdefg-000-000-0000-abcdefg',
  api_id: 'abcd1234',
  resource_path: '/',
  resource_id: 'efg567',
  http_method: 'GET',
  source_ip: '192.0.2.1',
  user-agent: 'curl/7.84.0',
  account_id: '111122223333',
  api_key: 'MyTestKey',
  caller: 'ABCD-0000-12345',
  user: 'ABCD-0000-12345',
  user_arn: 'arn:aws:sts::111122223333:assumed-role/Admin/carlos-salazar'
}
```

変数の 1 つは API キーです。この例では、メソッドが 1 つの API キーを要求することを前提としています。

## 例 2: すべてのリクエストパラメータを JSON ペイロードを介して統合エンドポイントに渡す
<a name="input-examples-mapping-templates"></a>

次の例では、`path` パラメータ、`querystring` パラメータ、`header` パラメータを含むすべてのリクエストパラメータを JSON ペイロードを介して統合エンドポイントに渡します。

```
#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}
```

リクエストに次の入力パラメータがある場合:
+ `myparam` という名前のパスパラメータ
+ クエリ文字列パラメータ `querystring1=value1,value2`
+ ヘッダー `"header1" : "value1"`

このマッピングテンプレートの出力は、次のようになります。

```
{"params":{"path":{"example2":"myparamm"},"querystring":{"querystring1":"value1,value2"},"header":{"header1":"value1"}}}
```

## 例 3: メソッドリクエストのサブセクションを統合エンドポイントに渡す
<a name="input-example-json-mapping-template"></a>

 次の例では、入力パラメータ `name` を使用して、パラメータ `name` のみを取得し、入力パラメータ `input.json('$')` を使用してメソッドリクエスト本文全体を取得します。

```
{
    "name" : "$input.params('name')",
    "body" : $input.json('$') 
}
```

クエリ文字列パラメータ `name=Bella&type=dog` と次の本文を含むリクエストの場合:

```
{
    "Price" : "249.99",
    "Age": "6"
}
```

このマッピングテンプレートの出力は、次のようになります。

```
{
    "name" : "Bella",
    "body" : {"Price":"249.99","Age":"6"}
}
```

このマッピングテンプレートは、クエリ文字列パラメータ `type=dog` を削除します。

 JSON の入力に JavaScript で解析できない文字がエスケープされずに含まれている場合、API Gateway は 400 レスポンスを返すことがあります。JSON の入力を正しく解析できるようにするには、`$util.escapeJavaScript($input.json('$'))` を適用します。

前の例に `$util.escapeJavaScript($input.json('$'))` を適用した結果は次のとおりです。

```
{
    "name" : "$input.params('name')",
    "body" : "$util.escapeJavaScript($input.json('$'))"
}
```

この場合、このマッピングテンプレートの出力は、次のようになります。

```
{
    "name" : "Bella",
    "body": {"Price":"249.99","Age":"6"}
}
```

## 例 4: JSONPath 式を使用してメソッドリクエストのサブセクションを統合エンドポイントに渡す
<a name="input-example-inputs-mapping-template"></a>

次の例では、JSONPath 式を使用して、リクエスト本文から入力パラメータ `name` と `Age` のみを取得します。

```
{
    "name" : "$input.params('name')",
    "body" : $input.json('$.Age')  
}
```

クエリ文字列パラメータ `name=Bella&type=dog` と次の本文を含むリクエストの場合:

```
{
    "Price" : "249.99",
    "Age": "6"
}
```

このマッピングテンプレートの出力は、次のようになります。

```
{
    "name" : "Bella",
    "body" : "6"
}
```

このマッピングテンプレートは、クエリ文字列パラメータ `type=dog` と `Price` フィールドを本文から削除します。

 メソッドリクエストのペイロードに JavaScript で解析できない文字がエスケープされずに含まれている場合、API Gateway は `400` レスポンスを返すことがあります。JSON の入力を正しく解析できるようにするには、`$util.escapeJavaScript()` を適用します。

前の例に `$util.escapeJavaScript($input.json('$.Age'))` を適用した結果は次のとおりです。

```
{
    "name" : "$input.params('name')",
    "body" : "$util.escapeJavaScript($input.json('$.Age'))" 
}
```

この場合、このマッピングテンプレートの出力は、次のようになります。

```
{
    "name" : "Bella",
    "body": "\"6\""
}
```

## 例 5: JSONPath 式を使用してメソッドリクエストに関する情報を統合エンドポイントに渡す
<a name="input-example-request-and-response"></a>

次の例では、`$input.params()`、`$input.path()`、`$input.json()` を使用して、メソッドリクエストに関する情報を統合エンドポイントに送信します。このマッピングテンプレートは、`size()` メソッドを使用してリスト内の要素の数を提供します。

```
{
    "id" : "$input.params('id')",
    "count" : "$input.path('$.things').size()",
    "things" : $input.json('$.things')
}
```

パスパラメータ `123` と次の本文を含むリクエストの場合:

```
{
      "things": {
            "1": {},
            "2": {},
            "3": {}
      }
}
```

このマッピングテンプレートの出力は、次のようになります。

```
{"id":"123","count":"3","things":{"1":{},"2":{},"3":{}}}
```

 メソッドリクエストのペイロードに JavaScript で解析できない文字がエスケープされずに含まれている場合、API Gateway は `400` レスポンスを返すことがあります。JSON の入力を正しく解析できるようにするには、`$util.escapeJavaScript()` を適用します。

前の例に `$util.escapeJavaScript($input.json('$.things'))` を適用した結果は次のとおりです。

```
{
     "id" : "$input.params('id')",
     "count" : "$input.path('$.things').size()",
     "things" : "$util.escapeJavaScript($input.json('$.things'))"
}
```

このマッピングテンプレートの出力は、次のようになります。

```
{"id":"123","count":"3","things":"{\"1\":{},\"2\":{},\"3\":{}}"}
```