メニュー
Amazon API Gateway
開発者ガイド

リクエストおよびレスポンスマッピングのモデルおよびマッピングテンプレートを作成する

API Gateway では、API のメソッドリクエストは、バックエンドで必要となる、該当する統合リクエストペイロードとは異なる形式のペイロードを受け取ることができます。同様に、バックエンドは、フロントエンドで予期されるメソッドレスポンスペイロードとは異なる統合レスポンスペイロードを返す場合があります。API Gateway では、マッピングテンプレートを使用して、ペイロードをメソッドリクエストから該当する統合リクエストにマッピングしたり、統合レスポンスから該当するメソッドレスポンスにマッピングしたりできます。

マッピングテンプレートは、Velocity Template Language(VTL) で表されるスクリプトであり、JSONPath 式を使用してペイロードに適用されます。ペイロードでは、JSON スキーマに基づくデータモデルを使用できます。このモデルは、API Gateway で SDK を生成する際や、API で基本的なリクエストの検証を有効にする際に定義する必要があります。マッピングテンプレートを作成する際にモデルを定義する必要はありません。ただし、API Gateway では指定されたモデルに基づいてテンプレート設計図が生成されるため、モデルを定義するとテンプレートの作成に役立ちます。

このセクションでは、モデルとマッピングテンプレートを使用して、API リクエストとレスポンスペイロードをマッピングする方法を説明します。

モデル

API Gateway では、モデルはペイロードのデータ構造を定義します。API Gateway では、JSON スキーマを使用してモデルを定義します。

次の JSON オブジェクトは、よくあるスーパーマーケットの青果部門の果物または野菜の在庫について記述したサンプルデータを示しています。

スーパーマーケットの青果部門で果物と野菜の在庫を管理するための API があるとします。マネージャーからバックエンドに現在の在庫についての問い合わせがあると、サーバーは次のレスポンスペイロードを送り返します。

Copy
{ "department": "produce", "categories": [ "fruit", "vegetables" ], "bins": [ { "category": "fruit", "type": "apples", "price": 1.99, "unit": "pound", "quantity": 232 }, { "category": "fruit", "type": "bananas", "price": 0.19, "unit": "each", "quantity": 112 }, { "category": "vegetables", "type": "carrots", "price": 1.29, "unit": "bag", "quantity": 57 } ] }

JSON オブジェクトには、3 つのプロパティがあります。

  • department プロパティは文字列値 (produce) を持ちます。

  • categories プロパティは、2 つの文字列 (fruitvegetables) の配列です。

  • bins プロパティはオブジェクトの配列です。各オブジェクトが文字列値または数値のプロパティ (categorytypepriceunitquantity) を持ちます。

上のデータのモデルを定義するには、次の JSON スキーマを使用できます。

Copy
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } } }

前のモデル例では、以下のようになっています。

  • $schema オブジェクトは、有効な JSON スキーマのバージョン識別子を表します。この例では、JSON スキーマのドラフト v4 を表します。

  • title オブジェクトは、人間が読めるモデルの識別子です。この例では、GroceryStoreInputModel です。

  • JSON データのトップレベル (ルート) 構造体はオブジェクトです。

  • JSON データのルートオブジェクトには、departmentcategoriesbins プロパティが格納されます。

  • department プロパティは JSON データの文字列オブジェクトです。

  • categories プロパティは JSON データの配列です。この配列には、JSON データの文字列値が格納されます。

  • bins プロパティは JSON データの配列です。この配列には、JSON データのオブジェクトが格納されます。JSON データのこれらの各オブジェクトには、category 文字列、type 文字列、price 数値、unit 文字列、quantity 整数 (小数部または指数部のない数字) が格納されます。

または、このスキーマの一部 (bins 配列の項目の定義など) を同じファイルの別のセクションに含め、$ref プリミティブを使用して、スキーマの他の部分でこの再利用可能な定義を参照することができます。$ref を使用して、上記のモデル定義ファイルを次のように表現できます。

Copy
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "$ref": "#/definitions/Bin" } } }, "definitions": { "Bin" : { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } }

definitions セクションには、bins 配列で "ref": "#/definitions/Bin" で参照される Bin 項目のスキーマ定義を含めることができます。このようにして再利用可能な定義を使用すると、モデル定義は読みやすくなります。

さらに、そのモデルの URL を $ref プロパティの値 "$ref": "https://apigateway.amazonaws.com/restapis/{restapi_id}/models/{model_name}" として設定することで、外部モデルファイルで定義された別のモデルスキーマを参照することもできます。たとえば、ID fugvjdxtri を使って API で作成された、Bin2 という名前の次の本格的なモデルがあるとします。

Copy
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "Bin" : { "type": "object", "properties": { "category": { "type": "string" }, "type": { "type": "string" }, "price": { "type": "number" }, "unit": { "type": "string" }, "quantity": { "type": "integer" } } } } }

次に示すように、同じ API の GroceryStoreInputModel から、これを参照できます。

Copy
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreInputModel", "type": "object", "properties": { "department": { "type": "string" }, "categories": { "type": "array", "items": { "type": "string" } }, "bins": { "type": "array", "items": { "$ref": "https://apigateway.amazonaws.com/restapis/fugvjdxtri/models/Bin2" } } } }

参照元および参照先モデルは、同じ API からのものである必要があります。

この例では、必須項目を指定したり、文字列、数値、配列項目の最大および最小許容長を指定したり、正規表現を使用したりするような、JSON スキーマの高度な機能は使用していません。詳細については、「Introducing JSON」と「JSON Schema」を参照してください。

より複雑な JSON データの形式とそれらのモデルについては、以下の例を参照してください。

API Gateway でモデルを試すには、「レスポンスペイロードをマッピングする」の「ステップ1: モデルを作成する」の手順に従ってください。

マッピングテンプレート

バックエンドから返されるクエリ結果 (Models セクション) は、次のように表示されると青果部門のマネージャーに役立つと思われます。

Copy
{ "choices": [ { "kind": "apples", "suggestedPrice": "1.99 per pound", "available": 232 }, { "kind": "bananas", "suggestedPrice": "0.19 per each", "available": 112 }, { "kind": "carrots", "suggestedPrice": "1.29 per bag", "available": 57 } ] }

これを有効にするには、データをバックエンド形式から変換するマッピングテンプレートを API Gateway に提供する必要があります。そのためには次のマッピングテンプレートを使用します。

Copy
#set($inputRoot = $input.path('$')) { "choices": [ #foreach($elem in $inputRoot.bins) { "kind": "$elem.type", "suggestedPrice": "$elem.price per $elem.unit", "available": $elem.quantity }#if($foreach.hasNext),#end #end ] }

この出力マッピングテンプレートの詳細について以下に説明します。

  • $inputRoot 変数は、前のセクションにおける元の JSON データのルートオブジェクトです。出力マッピングテンプレートの変数は、変換後の JSON データスキーマではなく、元の JSON データにマッピングされています。

  • 出力マッピングテンプレートの choices 配列は、元の JSON データのルートオブジェクト ($inputRoot.bins) の bins 配列からマッピングされます。

  • 出力マッピングテンプレートで、choices 配列の各オブジェクト ($elem) は、元の JSON データのルートオブジェクト内の bins 配列の対応するオブジェクトからマッピングされます。

  • 出力マッピングテンプレートの choices オブジェクト内のオブジェクトごとに、kind オブジェクトと available オブジェクトの値 ($elem.type および $elem.quantity) は、元の JSON データの bins 配列内のオブジェクトごとの type オブジェクトと value オブジェクトの対応する値からそれぞれマッピングされます。

  • 出力マッピングテンプレートの choices オブジェクト内のオブジェクトごとに、suggestedPrice オブジェクトの値は、元の JSON データのオブジェクトごとに、price オブジェクトと unit オブジェクトの対応する値にそれぞれ連結されて、各値は per という単語で区切られます。

Velocity Template Language の詳細については、「Apache Velocity - VTL Reference」を参照してください。JSONPath の詳細については、「JSONPath - XPath for JSON」を参照してください。

マッピングテンプレートでは、基盤となるデータが JSON オブジェクトであることを前提としています。データのモデルを定義する必要はありません。API 開発者は、フロントエンドとバックエンドの両方のデータ形式を知っています。その知識があれば、形式を混同することはなく、必要なマッピングを定義できます。

API 用の SDK を生成するために、上のデータが言語固有のオブジェクトとして返されます。Java、Objective-C、Swift などの厳密に型指定された言語では、オブジェクトはユーザー定義データ型 (UDT) に対応します。API Gateway にデータモデルを提供すると、このような UDT が作成されます。上のメソッドレスポンス例では、統合レスポンスで次のペイロードモデルを定義できます。

Copy
{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "GroceryStoreOutputModel", "type": "object", "properties": { "choices": { "type": "array", "items": { "type": "object", "properties": { "kind": { "type": "string" }, "suggestedPrice": { "type": "string" }, "available": { "type": "integer" } } } } } }

このモデルでは、JSON スキーマは以下のように表現されています。

  • $schema オブジェクトは、有効な JSON スキーマのバージョン識別子を表します。この例では、JSON スキーマのドラフト v4 を表します。

  • title オブジェクトは、人間が読めるモデルの識別子です。この例では、GroceryStoreOutputModel です。

  • JSON データのトップレベル (ルート) 構造体はオブジェクトです。

  • JSON データのルートオブジェクトには、オブジェクトの配列が格納されます。

  • このオブジェクトの配列内の各オブジェクトには、kind 文字列、suggestedPrice 文字列、available 整数 (小数部または指数部のない数字) が格納されます。

このモデルでは、SDK を呼び出して GroceryStoreOutputModel.kindGroceryStoreOutputModel.suggestedPrice、および GroceryStoreOutputModel.available の各プロパティを読み取ることで、kindsuggestedPrice、および available の各プロパティ値を取得できます。モデルが指定されていない場合、API Gateway は空のモデルを使用してデフォルトの UDT を作成します。この場合、厳密に型指定された SDK を使用して、これらのプロパティを読み取ることはできません。

より複雑なマッピングテンプレートを試すには、以下の例を参照してください。

API Gateway でマッピングテンプレートを試すには、「レスポンスペイロードをマッピングする」の「ステップ 5: メソッドをセットアップし、テストする」の手順に従ってください。

モデルとマッピングテンプレートでの作業

モデルとマッピングテンプレートで行えるその他の作業については、以下を参照してください。