

# Mapping template transformations for REST APIs in API Gateway
<a name="models-mappings"></a>

A mapping template transformation uses a mapping template to modify your integration request or integration response. A *mapping template* is a script expressed in [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) and applied to a payload using [JSONPath ](https://goessner.net/articles/JsonPath/) based on the `Content-type` header. You use mapping templates when you use mapping template transformations. This section describes conceptual information related to mapping templates.

The following diagram shows the request lifecycle for a `POST /pets` resource that has an integration with a PetStore integration endpoint. In this API, a user sends data about a pet and the integration endpoint returns the adoption fee associated with a pet. In this request lifecycle, mapping template transformations filter the request body to the integration endpoint and filter the response body from the integration endpoint.

![\[Example request lifecycle\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/mapping-template-transforms.png)


The following sections explain the request and response lifecycle.

## Method request and integration request
<a name="models-mappings-request"></a>

In the previous example, if this is the request body sent to the method request:

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

This request body is not in the correct format to be used by the integration endpoint, so API Gateway performs a mapping template transformation. API Gateway only performs a mapping template transformation because there is a mapping template defined for the Content-Type `application/json`. If you don't define a mapping template for the Content-Type, by default, API Gateway passes the body through the integration request to the integration endpoint. To modify this behavior, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md).

The following mapping template transforms the method request data in the integration request before it's sent to the integration endpoint:

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

1. The `$inputRoot` variable represents the root object in the original JSON data from the previous section. Directives begin with the `#` symbol.

1. The `dog` is a concatenation of the user's `id` and a string value.

1. `Age` is from the method request body.

Then, the following output is forwarded to the integration endpoint:

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

## Integration response and method response
<a name="models-mappings-response"></a>

After the successful request to the integration endpoint, the endpoint sends a response to API Gateway's integration response. The following is the example output data from the integration endpoint:

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

The method response expects a different payload than what is returned by the integration response. API Gateway performs a mapping template transformation. API Gateway only performs a mapping template transformation because there is a mapping template defined for the Content-Type `application/json`. If you don't define a mapping template for the Content-Type, by default, API Gateway passes the body through the integration response to the method response. To modify this behavior, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md).

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

The following output is sent to the method response:

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

This completes the example mapping template transformation. We recommend that when possible, instead of using mapping template transformations, you use a proxy integration to transform your data. For more information, see [Choose an API Gateway API integration type](api-gateway-api-integration-types.md).

# Method request behavior for payloads without mapping templates for REST APIs in API Gateway
<a name="integration-passthrough-behaviors"></a>

If your method request has a payload and you don't have a mapping template defined for the `Content-Type` header, you can choose to pass the client-supplied request payload through the integration request to the backend without transformation. The process is known as integration passthrough. 

 The actual passthrough behavior of an incoming request is determined by this setting. There are three options: 

**When no template matches the request Content-Type header**  
Choose this option if you want the method request body to pass through the integration request to the backend without transformation when the method request content type does not match any content types associated with the mapping templates.  
When calling the API Gateway API, you choose this option by setting `WHEN_NO_MATCH` as the `passthroughBehavior` property value on the [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html).

**When there are no templates defined (recommended)**  
Choose this option if you want the method request body to pass through the integration request to the backend without transformation when no mapping template is defined in the integration request. If a template is defined when this option is selected, the method request with a payload and content type that doesn't match any defined mapping template will be rejected with an HTTP 415 Unsupported Media Type response.  
When calling the API Gateway API, you choose this option by setting `WHEN_NO_TEMPLATES` as the `passthroughBehavior` property value on the [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html).

**Never**  
Choose this option if you do not want the method request body to pass through the integration request to the backend without transformation when no mapping template is defined in the integration request. If a template is defined when this option is selected, the method request of an unmapped content type will be rejected with an HTTP 415 Unsupported Media Type response.   
When calling the API Gateway API, you choose this option by setting `NEVER` as the `passthroughBehavior` property value on the [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html).

 The following examples show the possible passthrough behaviors. 

Example 1: One mapping template is defined in the integration request for the `application/json` content type.


| Content-type | Passthrough option | Behavior | 
| --- | --- | --- | 
| None API Gateway defaults to `application/json` | WHEN\$1NO\$1MATCH | The request payload is transformed using the template. | 
| None API Gateway defaults to `application/json` | WHEN\$1NO\$1TEMPLATES | The request payload is transformed using the template. | 
| None API Gateway defaults to `application/json` | NEVER | The request payload is transformed using the template. | 
| application/json | WHEN\$1NO\$1MATCH | The request payload is transformed using the template. | 
| application/json | WHEN\$1NO\$1TEMPLATES | The request payload is transformed using the template. | 
| application/json | NEVER | The request payload is transformed using the template. | 
| application/xml | WHEN\$1NO\$1MATCH | The request payload is not transformed and is sent to the backend as-is. | 
| application/xml | WHEN\$1NO\$1TEMPLATES | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| application/xml | NEVER | The request is rejected with an HTTP 415 Unsupported Media Type response. | 

Example 2: One mapping template is defined in the integration request for the `application/xml` content type.


| Content-type | Passthrough option | Behavior | 
| --- | --- | --- | 
| None API Gateway defaults to `application/json` | WHEN\$1NO\$1MATCH | The request payload is not transformed and is sent to the backend as-is. | 
| None API Gateway defaults to `application/json` | WHEN\$1NO\$1TEMPLATES | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| None API Gateway defaults to `application/json` | NEVER | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| application/json | WHEN\$1NO\$1MATCH | The request payload is not transformed and is sent to the backend as-is. | 
| application/json | WHEN\$1NO\$1TEMPLATES | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| application/json | NEVER | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| application/xml | WHEN\$1NO\$1MATCH | The request payload is transformed using the template. | 
| application/xml | WHEN\$1NO\$1TEMPLATES | The request payload is transformed using the template. | 
| application/xml | NEVER | The request payload is transformed using the template. | 

Example 3: No mapping templates are defined in the integration request.


| Content-type | Passthrough option | Behavior | 
| --- | --- | --- | 
| None API Gateway defaults to `application/json` | WHEN\$1NO\$1MATCH | The request payload is not transformed and is sent to the backend as-is. | 
| None API Gateway defaults to `application/json` | WHEN\$1NO\$1TEMPLATES | The request payload is not transformed and is sent to the backend as-is. | 
| None API Gateway defaults to `application/json` | NEVER | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| application/json | WHEN\$1NO\$1MATCH | The request payload is not transformed and is sent to the backend as-is. | 
| application/json | WHEN\$1NO\$1TEMPLATES | The request payload is not transformed and is sent to the backend as-is. | 
| application/json | NEVER | The request is rejected with an HTTP 415 Unsupported Media Type response. | 
| application/xml | WHEN\$1NO\$1MATCH | The request payload is not transformed and is sent to the backend as-is. | 
| application/xml | WHEN\$1NO\$1TEMPLATES | The request payload is not transformed and is sent to the backend as-is. | 
| application/xml | NEVER | The request is rejected with an HTTP 415 Unsupported Media Type response. | 

# Additional mapping template example for REST APIs in API Gateway
<a name="example-photos"></a>

The following example shows a photo album API in API Gateway that uses mapping templates to transform integration request and integration response data. It also uses data models to define method request and integration response payloads. For more information about data models, see [Data models for REST APIs](models-mappings-models.md).

## Method request and integration request
<a name="example-photos-request"></a>

The following is a model that defines the method request body. This input model requires that the caller upload one photo page, and requires a minimum of 10 photos for each page. You can use this input model to generate an SDK or to use request validation for your API. While using request validation, if the method request body doesn't adhere to the data structure of the model, API Gateway fails the request. 

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

The following is an example method request body that adheres to the data structure of the previous data model.

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

In this example, if the previous method request body was submitted by the client, then this mapping template transforms the payload to match the format required by the integration endpoint.

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

The following example is output data from the transformation:

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

This data is sent to the integration request, and then to the integration endpoint.

## Integration response and method response
<a name="photos-example-response"></a>

The following is an example output model for the photo data from the integration endpoint. You can use this model for a method response model, which is necessary when you generate a strongly typed SDK for the API. This causes the output to be cast into an appropriate class in Java or 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" }
        }
      }
    }
  }
}
```

The integration endpoint might not respond with a response that adheres to the data structure of this model. For instance, the integration response might look like the following:

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

The following example mapping template transforms the integration response data into the format expected by the method response:

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

The following example is output data from the transformation:

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

This data is sent to the method response and then back to the client.

# Override your API's request and response parameters and status codes for REST APIs in API Gateway
<a name="apigateway-override-request-response-parameters"></a>

You can use mapping template transformations to override any type of request parameter, response header, or response status code. You use a mapping template to do the following:
+ Perform many-to-one parameter mappings
+ Override parameters after standard API Gateway mappings have been applied
+ Conditionally map parameters based on body content or other parameter values
+ Programmatically create new parameters
+ Override status codes returned by your integration endpoint

Overrides are final. An override may only be applied to each parameter once. If you try to override the same parameter multiple times, API Gateway returns a `5XX` response. If you must override the same parameter multiple times throughout the template, we recommend creating a variable and applying the override at the end of the template. The template is applied only after the entire template is parsed.

## Example 1: Override the status code based on the integration body
<a name="apigateway-override-request-response-examples"></a>

The following example use the [example API](api-gateway-create-api-from-example.md) to override the status code based on the integration response body.

------
#### [ AWS Management Console ]

**To override a status code based on the integration response body**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose **Create API**.

1. For **REST API**, choose **Build**.

1. For **API details**, choose **Example API**.

1. Choose **Create API**.

   API Gateway creates an example pet store API. To retrieve information about a pet, you use the API method request of `GET /pets/{petId}`, where `{petId}` is a path parameter corresponding to an ID number for a pet.

   In this example, you override the `GET` method's response code to `400` when an error condition is detected.

1. In the **Resources** tree, choose the `GET` method under `/{petId}`.

1. First, you test the current implementation of the API. 

   Choose the **Test** tab. You might need to choose the right arrow button to show the tab.

1. For **petId**, enter **-1**, and then choose **Test**.

   The **Response body** indicates an out-of-range error:

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

   In addition, the last line under **Logs** ends with: `Method completed with status: 200`.

   The integration was completed successfully, but there was an error. Now you'll override the status code based on the integration response.

1. On the **Integration response** tab, for the **Default - Response**, choose **Edit**.

1. Choose **Mapping templates**.

1. Choose **Add mapping template**.

1. For **Content type**, enter **application/json**.

1. For **Template body**, enter the following:

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

   This mapping template uses the `$context.responseOverride.status` variable to override the status code to `400` if the integration response contains the string `error`.

1. Choose **Save**.

1. Choose the **Test** tab.

1. For **petId**, enter **-1**.

1. In the results, the **Response Body** indicates an out-of-range error:

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

   However, the last line under **Logs** now ends with: `Method completed with status: 400`.

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

 In this example, you use the [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) property to import an OpenAPI definition file into 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 ]

The following OpenAPI definition creates the `GET pets/{petId}` resource and overrides the status code based on the integration 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('$'))\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"
          }
        }
      }
    }
  }
}
```

------

## Example 2: Override the request header and create new headers
<a name="apigateway-override-request-response-examples-2"></a>

The following example uses the [example API](api-gateway-create-api-from-example.md) to override the request header and create new headers.

------
#### [ AWS Management Console ]

**To override a method's request header by creating a new header**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Choose the example API you created in the previous tutorial. The name of the API should be **PetStore**.

1. In the **Resources** tree, choose the `GET` method under `/pet`.

1. On the **Method request** tab, for **Method request settings**, choose **Edit**.

1. Choose **HTTP request headers**, and then choose **Add header**.

1. For **Name**, enter **header1**.

1. Choose **Add header**, and then create a second header called **header2**.

1. Choose **Save**.

   Now, you combine these headers into one header value using a mapping template.

1. On the **Integration request** tab, for **Integration request settings**, choose **Edit**.

1. For **Request body passthrough**, select **When there are no templates defined (recommended)**.

1. Choose **Mapping templates**, and then do the following:

   1. Choose **Add mapping template**.

   1. For **Content type**, enter **application/json**. 

   1. For **Template body**, enter the following:

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

      This mapping template overrides `header1` with the string `pets` and creates a multi-value header called `$header3Value` that combines `header1` and `header2`.

1. Choose **Save**.

1. Choose the **Test** tab.

1. Under **Headers**, copy the following code:

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

1. Choose **Test**.

   In the **Logs**, you should see an entry that includes this text:

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

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

 In this example, you use the [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) property to import an OpenAPI definition file into 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 ]

 The following OpenAPI definition creates the `GET pets` resource and overrides the request header and create new headers.

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

------

To use a mapping template override, add one or more of the following `$context` variables. For a list of `$context` variables, see [Context variables for data transformations](api-gateway-mapping-template-reference.md#context-variable-reference).

# Tutorial: Modify the integration request and response for integrations to AWS services
<a name="set-up-data-transformations-in-api-gateway"></a>

The following tutorial shows how to use mapping template transformations to set up mapping templates to transform integration requests and responses using the console and AWS CLI.

**Topics**
+ [

## Set up data transformation using the API Gateway console
](#mapping-example-console)
+ [

## Set up data transformation using the AWS CLI
](#mapping-example-cli)
+ [

## Completed data transformation CloudFormation template
](#api-gateway-data-transformations-full-cfn-stack)

## Set up data transformation using the API Gateway console
<a name="mapping-example-console"></a>

In this tutorial, you will create an incomplete API and DynamoDB table using the following .zip file [data-transformation-tutorial-console.zip](samples/data-transformation-tutorial-console.zip). This incomplete API has a `/pets` resource with `GET` and `POST` methods. 
+ The `GET` method will get data from the `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP endpoint. The output data will be transformed according to the mapping template in [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).
+ The `POST` method will allow the user to `POST` pet information to a Amazon DynamoDB table using a mapping template.

Download and unzip [the app creation template for CloudFormation](samples/data-transformation-tutorial-console.zip). You'll use this template to create a DynamoDB table to post pet information and an incomplete API. You will finish the rest of the steps in the API Gateway console. 

**To create an CloudFormation stack**

1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Choose **Create stack** and then choose **With new resources (standard)**.

1. For **Specify template**, choose **Upload a template file**.

1. Select the template that you downloaded.

1. Choose **Next**. 

1. For **Stack name**, enter **data-transformation-tutorial-console** and then choose **Next**.

1. For **Configure stack options**, choose **Next**.

1. For **Capabilities**, acknowledge that CloudFormation can create IAM resources in your account.

1. Choose **Next**, and then choose **Submit**.

CloudFormation provisions the resources specified in the template. It can take a few minutes to finish provisioning your resources. When the status of your CloudFormation stack is **CREATE\$1COMPLETE**, you're ready to move on to the next step.

**To test the `GET` integration response**

1. On the **Resources** tab of the CloudFormation stack for **data-transformation-tutorial-console**, select the physical ID of your API.

1. In the main navigation pane, choose **Resources**, and then select the **GET** method. 

1. Choose the **Test** tab. You might need to choose the right arrow button to show the tab.

   The output of the test will show the following: 

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

   You will transform this output according to the mapping template in [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).

**To transform the `GET` integration response**

1. Choose the **Integration response** tab.

   Currently, there are no mapping templates defined, so the integration response will not be transformed. 

1. For **Default - Response**, choose **Edit**.

1. Choose **Mapping templates**, and then do the following:

   1. Choose **Add mapping template**.

   1. For **Content type**, enter **application/json**. 

   1. For **Template body**, enter the following:

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

   Choose **Save**.

**To test the `GET` integration response**
+ Choose the **Test** tab, and then choose **Test**.

  The output of the test will show the transformed response. 

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

**To transform input data from the `POST` method**

1. Choose the **POST** method.

1. Choose the **Integration request** tab, and then for **Integration request settings**, choose **Edit**.

   The CloudFormation template has populated some of the integration request fields. 
   +  The integration type is AWS service. 
   +  The AWS service is DynamoDB. 
   +  The HTTP method is `POST`. 
   +  The Action is `PutItem`. 
   +  The Execution role allowing API Gateway to put an item into the DynamoDB table is `data-transformation-tutorial-console-APIGatewayRole`. CloudFormation created this role to allow API Gateway to have the minimal permissions for interacting with DynamoDB. 

    The name of the DynamoDB table has not been specified. You will specify the name in the following steps. 

1. For **Request body passthrough**, select **Never**.

   This means that the API will reject data with Content-Types that do not have a mapping template.

1. Choose **Mapping templates**.

1. The **Content type** is set to `application/json`. This means a content types that are not application/json will be rejected by the API. For more information about the integration passthrough behaviors, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md)

1. Enter the following code into the text editor.

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

    This template specifies the table as `data-transformation-tutorial-console-ddb` and sets the items as `id`, `type`, and `price`. The items will come from the body of the `POST` method. You also can use a data model to help create a mapping template. For more information, see [Request validation for REST APIs in API Gateway](api-gateway-method-request-validation.md). 

1. Choose **Save** to save your mapping template. 

**To add a method and integration response from the `POST` method**

The CloudFormation created a blank method and integration response. You will edit this response to provide more information. For more information about how to edit responses, see [Parameter mapping examples for REST APIs in API Gateway](request-response-data-mappings.md).

1. On the **Integration response** tab, for **Default - Response**, choose **Edit**.

1. Choose **Mapping templates**, and then choose **Add mapping template**.

1. For **Content-type**, enter **application/json**.

1. In the code editor, enter the following output mapping template to send an output message:

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

   For more information about context variables, see [Context variables for data transformations](api-gateway-mapping-template-reference.md#context-variable-reference).

1. Choose **Save** to save your mapping template. 

**Test the `POST` method**

Choose the **Test** tab. You might need to choose the right arrow button to show the tab.

1. In the request body, enter the following example.

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

1. Choose **Test**.

   The output should show your success message.

    You can open the DynamoDB console at [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) to verify that the example item is in your table. 

**To delete an CloudFormation stack**

1. Open the CloudFormation console at [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Select your CloudFormation stack.

1. Choose **Delete** and then confirm your choice.

## Set up data transformation using the AWS CLI
<a name="mapping-example-cli"></a>

In this tutorial, you will create an incomplete API and DynamoDB table using the following .zip file [data-transformation-tutorial-cli.zip](samples/data-transformation-tutorial-cli.zip). This incomplete API has a `/pets` resource with a `GET` method integrated with the `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP endpoint. You will create a `POST` method to connect to a DynamoDB table and use mapping templates to input data into a DynamoDB table. 
+ You will transform the output data according to the mapping template in [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).
+ You will create a `POST` method to allow the user to `POST` pet information to a Amazon DynamoDB table using a mapping template.

**To create an CloudFormation stack**

Download and unzip [the app creation template for CloudFormation](samples/data-transformation-tutorial-cli.zip). 

To complete the following tutorial, you need the [AWS Command Line Interface (AWS CLI) version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). 

For long commands, an escape character (`\`) is used to split a command over multiple lines.
**Note**  
In Windows, some Bash CLI commands that you commonly use (such as `zip`) are not supported by the operating system's built-in terminals. To get a Windows-integrated version of Ubuntu and Bash, [install the Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install). Example CLI commands in this guide use Linux formatting. Commands which include inline JSON documents must be reformatted if you are using the Windows CLI. 

1.  Use the following command to create the CloudFormation stack.

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

1. CloudFormation provisions the resources specified in the template. It can take a few minutes to finish provisioning your resources. Use the following command to see the status of your CloudFormation stack.

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

1. When the status of your CloudFormation stack is `StackStatus: "CREATE_COMPLETE"`, use the following command to retrieve relevant output values for future steps.

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

   The output values are the following:
   + ApiRole, which is the role name that allows API Gateway to put items in the DynamoDB table. For this tutorial, the role name is `data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG`.
   + DDBTableName, which is the name of the DynamoDB table. For this tutorial, the table name is `data-transformation-tutorial-cli-ddb`
   + ResourceId, which is the ID for the pets resource where the `GET` and `POST` methods are exposed. For this tutorial, the Resource ID is `efg456`
   + ApiId, which is the ID for the API. For this tutorial, the API ID is `abc123`.

**To test the `GET` method before data transformation**
+ Use the following command to test the `GET` method. 

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

  The output of the test will show the following.

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

  You will transform this output according to the mapping template in [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).

**To transform the `GET` integration response**
+ Use the following command to update the integration response for the `GET` method. Replace the *rest-api-id* and *resource-id* with your values.

  Use the following command to create the integration response.

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

**To test the `GET` method**
+ Use the following command to test the `GET` method.

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

  The output of the test will show the transformed response. 

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

**To create a `POST` method**

1. Use the following command to create a new method on the `/pets` resource.

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

   This method will allow you to send pet information to the DynamoDB table that your created in the CloudFormation stack.

1.  Use the following command to create an AWS service integration on the `POST` method.

   ```
   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 the following command to create a method response for a successful call of the `POST` method. 

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

1. Use the following command to create an integration response for the successful call of the `POST` method.

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

**To test the `POST` method**
+ Use the following command to test the `POST` method.

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

  The output will show the successful message.

**To delete an CloudFormation stack**
+ Use the following command to delete your CloudFormation resources.

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

## Completed data transformation CloudFormation template
<a name="api-gateway-data-transformations-full-cfn-stack"></a>

The following example is a completed CloudFormation template, which creates an API and a DynamoDB table with a `/pets` resource with `GET` and `POST` methods. 
+ The `GET` method will get data from the `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP endpoint. The output data will be transformed according to the mapping template in [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).
+ The `POST` method will allow the user to `POST` pet information to a DynamoDB table using a mapping template.

### Example CloudFormation template
<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
```

# Examples using variables for mapping template transformations for API Gateway
<a name="api-gateway-mapping-variable-examples"></a>

The following examples show how to use `$context`, `input`, and `util` variables in mapping templates. You can use a mock integration or a Lambda non-proxy integration that returns the input event back to API Gateway. For a list of all supported variables for data transformations, see [Variables for data transformations for API Gateway](api-gateway-mapping-template-reference.md).

## Example 1: Pass multiple `$context` variables to the integration endpoint
<a name="context-variables-template-example"></a>

The following example shows a mapping template that maps incoming `$context` variables to backend variables with slightly different names in an integration request payload:

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

The output of this mapping template should look like the following:

```
{
  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'
}
```

One of the variables is an API key. This example assumes that the method requires an API key.

## Example 2: Pass all request parameters to the integration endpoint via a JSON payload
<a name="input-examples-mapping-templates"></a>

The following example passes all request parameters, including `path`, `querystring`, and `header` parameters, through to the integration endpoint via a JSON payload:

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

If a request has the following input parameters:
+ A path parameter named `myparam`
+ Query string parameters `querystring1=value1,value2`
+ Headers `"header1" : "value1"`.

The output of this mapping template should look like the following:

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

## Example 3: Pass a subsection of a method request to the integration endpoint
<a name="input-example-json-mapping-template"></a>

 The following example uses the input parameter `name` to retrieve only the `name` parameter and the input parameter `input.json('$')` to retrieve the entire body of the method request:

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

For a request that includes the query string parameters `name=Bella&type=dog` and the following body:

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

The output of this mapping template should look like the following:

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

This mapping template removes the query string parameter `type=dog`.

 If the JSON input contains unescaped characters that cannot be parsed by JavaScript, API Gateway might return a 400 response. Apply `$util.escapeJavaScript($input.json('$'))` to ensure the JSON input can be parsed properly. 

The previous example with `$util.escapeJavaScript($input.json('$'))` applied is as follows:

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

In this case, the output of this mapping template should look like the following:

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

## Example 4: Use JSONPath expression to pass a subsection of a method request to the integration endpoint
<a name="input-example-inputs-mapping-template"></a>

The following example uses the JSONPath expressions to retrieve only the input parameter `name` and the `Age` from the request body:

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

For a request that includes the query string parameters `name=Bella&type=dog` and the following body:

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

The output of this mapping template should look like the following:

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

This mapping template removes the query string parameter `type=dog` and the `Price` field from the body.

 If a method request payload contains unescaped characters that cannot be parsed by JavaScript, API Gateway might return a `400` response. Apply `$util.escapeJavaScript()` to ensure the JSON input can be parsed properly.

The previous example with `$util.escapeJavaScript($input.json('$.Age'))` applied is as follows:

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

In this case, the output of this mapping template should look like the following:

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

## Example 5: Use a JSONPath expression to pass information about a method request to the integration endpoint
<a name="input-example-request-and-response"></a>

The following example uses `$input.params()`, `$input.path()`, and `$input.json()` to send information about a method request to the integration endpoint. This mapping template uses the `size()` method to provide the number of elements in a list.

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

For a request that includes the path parameter `123` and the following body:

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

The output of this mapping template should look like the following:

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

 If a method request payload contains unescaped characters that cannot be parsed by JavaScript, API Gateway might return a `400` response. Apply `$util.escapeJavaScript()` to ensure the JSON input can be parsed properly.

The previous example with `$util.escapeJavaScript($input.json('$.things'))` applied is as follows:

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

The output of this mapping template should look like the following:

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