Menu
Amazon API Gateway
Developer Guide

Create Models and Mapping Templates for Request and Response Mappings

In API Gateway, an API's method request can take a payload in a different format from the corresponding integration request payload, as required in the back end. Similarly, the back end may return an integration response payload different from the method response payload, as expected by the front end. API Gateway lets you map the payload from a method request to the corresponding integration request and from an integration response to the corresponding method response. You use mapping templates to specify the mapping and can create model to facilitate the template generation. The section explains how to map the API request and response payload using models and mapping templates.

Models

In API Gateway, a model defines the structure or shape of a payload and is also known as the schema of the payload. API Gateway requires that the JSON Schema be used to describe the model of a JSON payload.

API Gateway maps a payload according to a mapping template. A model is useful, but not required, to generate a template. However, models are necessary for generating strongly typed SDK of your API. They can also be useful to validate a payload.

The following JSON object describes a sample data describing the fruit or vegetable inventory in the produce department of a likely supermarket:

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 } ] }

The JSON object has three properties

  • The department property has a string value (produce).

  • The categories property is an array of two strings: fruit and vegetables.

  • The bins property is an array of objects, each having the string- or number-valued properties of category, type, price, unit and quantity.

We express the corresponding model in the following JSON Schema notation:

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" } } } } } }

In the preceding example:

  • The $schema object represents a valid JSON Schema version identifier. In this example, it refers to JSON Schema, draft v4.

  • The title object is a human-readable identifier for the model. In this example, it is GroceryStoreInputModel.

  • The top-level, or root, construct in the JSON data is an object.

  • The root object in the JSON data contains department, categories, and bins properties.

  • The department property is a string object in the JSON data.

  • The categories property is an array in the JSON data. The array contains string values in the JSON data.

  • The bins property is an array in the JSON data. The array contains objects in the JSON data. Each of these objects in the JSON data contains a category string, a type string, a price number, a unit string, and a quantity integer (a number without a fraction or exponent part).

Alternatively, you could include part of this schema, for example, the item definition of the bins array, in a separate section of the same file and use the $ref primitive to reference this reusable definition in other parts of the schema. Using $ref, the above model definition file can be expressed as follows:

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" } } } } }

The definitions section contains the schema definition of the Bin item that is referenced in the bins array with "ref": "#/definitions/Bin". Using reusable definitions this way makes your model definition easier to read.

In addition, you can also reference another model schema defined in an external model file by setting that model's URL as the value of the $ref property: "$ref": "https://apigateway.amazonaws.com/restapis/{restapi_id}/models/{model_name}". For example, supposed you have the following full-fledged model named Bin2 created under an API with an identifier of fugvjdxtri:

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" } } } } }

You can then reference it from the GroceryStoreInputModel from the same API, as shown as follows:

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" } } } }

The referencing and referenced models must be from the same API.

The examples do not use advanced JSON Schema features, such as specifying required items; minimum and maximum allowed string lengths, numeric values, and array item lengths; regular expressions; and more. For more information, see Introducing JSON and JSON Schema.

For more complex JSON data formats and their models, see the following examples:

To experiment with models in API Gateway, follow the instructions in Map Response Payload, specifically Step 1: Create Models.

Mapping Templates

In API Gateway, a mapping template is used to transform some data from one format to another. You create and use input mapping templates and output mapping templates when you need to inform API Gateway about the schema of the data being sent from or returned to the caller, respectively. API Gateway uses the Velocity Template Language (VTL) and JSONPath expressions to define mapping templates.

For an example of an input mapping template, consider the example JSON data from the previous section. The following input mapping template makes no transform to the JSON data as API Gateway receives the JSON data from the caller:

Copy
#set($inputRoot = $input.path('$')) { "department": "$inputRoot.department", "categories": [ #foreach($elem in $inputRoot.categories) "$elem"#if($foreach.hasNext),#end #end ], "bins" : [ #foreach($elem in $inputRoot.bins) { "category" : "$elem.category", "type" : "$elem.type", "price" : $elem.price, "unit" : "$elem.unit", "quantity" : $elem.quantity }#if($foreach.hasNext),#end #end ] }

The preceding input mapping template is expressed as follows:

  • Let the variable $inputRoot in the input mapping template represent the root object in the original JSON data.

  • The values of the department object and categories and bins arrays in the input mapping template (represented by $inputRoot.department, $inputRoot.categories, and $inputRoot.bins) map to the corresponding values of the department object and categories and bins arrays in the root object in the original JSON data.

  • In the input mapping template, each of the values in the categories array (represented by the first $elem), and each of the objects in the bins array (represented by the second $elem), map to the corresponding values in the categories array and objects in the bins array, respectively, within the root object in the original JSON data.

  • For each of objects in the bins object, the values of the category, type, price, unit, and quantity objects in the input mapping template (represented by $elem.category, $elem.type, $elem.price, $elem.unit, and $elem.quantity, respectively) map to the corresponding values of the category, type, price, unit, and quantity objects in the original JSON data, respectively.

For an example of an output mapping template, first consider the following JSON data schema, which is based on the example JSON data from the previous section.

Note

None of the array and object names in this JSON data schema match the JSON data from the previous section:

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 } ] }

To transform the example JSON data from the previous section into this JSON data schema, you would use the following model:

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" } } } } } }

In the preceding example, the JSON schema is expressed as follows:

  • The $schema object represents a valid JSON Schema version identifier. In this example, it refers to JSON Schema, draft v4.

  • The title object is a human-readable identifier for the model. In this example, it is GroceryStoreOutputModel.

  • The top-level, or root, construct in the JSON data is an object.

  • The root object in the JSON data contains an array of objects.

  • Each object in the array of objects contains a kind string, a suggestedPrice string, and an available integer (a number without a fraction or exponent part).

You would then use the following output mapping template, which is based on this model:

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 ] }

The preceding output mapping template is expressed as follows:

  • Let the variable $inputRoot in the output mapping template represent the root object in the original JSON data from the previous section. Note the variables in the output mapping template map to the original JSON data, not the desired transformed JSON data schema.

  • The choices array in the output mapping template maps to the bins array with the root object in the original JSON data ($inputRoot.bins).

  • In the output mapping template, each of the objects in the choices array (represented by $elem) map to the corresponding objects in the bins array within the root object in the original JSON data.

  • In the output mapping template, for each of objects in the choices object, the values of the kind and available objects (represented by $elem.type and $elem.quantity) map to the corresponding values of the type and value objects in each of the objects in the original JSON data's bins array, respectively.

  • In the output mapping template, for each of objects in the choices object, the value of the suggestedPrice object is a concatenation of the corresponding value of the price and unit objects in each of the objects in the original JSON data, respectively, with each value separated by the word per.

For more information about the Velocity Template Language, see Apache Velocity - VTL Reference. For more information about JSONPath, see JSONPath - XPath for JSON.

To explore more complex mapping templates, see the following examples:

To experiment with mapping templates in API Gateway, follow the instructions in Map Response Payload, specifically Step 5: Set Up and Test the Methods.

Tasks for Models and Mapping Templates

For additional things you can do with models and mapping templates, see the following: