

# Develop REST APIs in API Gateway
Develop

 In Amazon API Gateway, you build a REST API as a collection of programmable entities known as API Gateway [resources](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html). For example, you use a [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource to represent an API that can contain a collection of [Resource](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html) entities. 

Each `Resource` entity can have one or more [Method](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html) resources. A `Method` is an incoming request submitted by the client and can contain the following request parameters: a path parameter, a header, or a query string parameter. In addition, depending on the HTTP method, the request can contain a body. Your method defines how the client accesses the exposed `Resource`. To integrate the `Method` with a backend endpoint, also known as the integration endpoint, you create an [Integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource. This forwards the incoming request to a specified integration endpoint URI. If necessary, you can transform request parameters or the request body to meet the backend requirements, or you can create a proxy integration, where API Gateway sends the entire request in a standardized format to the integration endpoint URI and then directly sends the response to the client.

For responses, you can create a [MethodResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html) resource to represent a response received by the client and you create an [IntegrationResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resource to represent the response that is returned by the backend. Use an integration response to transform the backend response data before returning the data to the client or to pass the backend response as-is to the client.

## Example resource for a REST API


The following diagram shows how API Gateway implements this request/response model for an HTTP proxy and an HTTP non-proxy integration for the `GET /pets` resource. The client sends the `x-version:beta` header to API Gateway and API Gateway sends the `204` status code to the client.

In the non-proxy integration, API Gateway performs data transformations to meet the backend requirements, by modifying the integration request and integration response. In a non-proxy integration, you can access the body in the method request but you transform it in the integration request. When the integration endpoint returns a response with a body, you access and transform it in the integration response. You can't modify the body in the method response.

In the proxy integration, the integration endpoint modifies the request and response. API Gateway doesn't modify the integration request or integration response, and sends the incoming request to the backend as-is.

Regardless of the integration type, the client sent a request to API Gateway and API Gateway responded synchronously.

------
#### [ Non-proxy integration ]

------
#### [ Proxy integration ]

------

The following example execution logs show what API Gateway would log in the previous example. For clarity, some values and initial logs have been removed:

------
#### [ Non-proxy integration ]

```
Wed Feb 12 23:56:44 UTC 2025 : Starting execution for request: abcd-1234-5678
Wed Feb 12 23:56:44 UTC 2025 : HTTP Method: GET, Resource Path: /pets
Wed Feb 12 23:56:44 UTC 2025 : Method request path: {}
Wed Feb 12 23:56:44 UTC 2025 : Method request query string: {}
Wed Feb 12 23:56:44 UTC 2025 : Method request headers: {x-version=beta}
Wed Feb 12 23:56:44 UTC 2025 : Method request body before transformations: 
Wed Feb 12 23:56:44 UTC 2025 : Endpoint request URI: http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:56:44 UTC 2025 : Endpoint request headers: {app-version=beta}
Wed Feb 12 23:56:44 UTC 2025 : Endpoint request body after transformations: 
Wed Feb 12 23:56:44 UTC 2025 : Sending request to http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:56:45 UTC 2025 : Received response. Status: 200, Integration latency: 123 ms
Wed Feb 12 23:56:45 UTC 2025 : Endpoint response headers: {Date=Wed, 12 Feb 2025 23:56:45 GMT}
Wed Feb 12 23:56:45 UTC 2025 : Endpoint response body before transformations:
Wed Feb 12 23:56:45 UTC 2025 : Method response body after transformations: (null)
Wed Feb 12 23:56:45 UTC 2025 : Method response headers: {X-Amzn-Trace-Id=Root=1-abcd-12345}
Wed Feb 12 23:56:45 UTC 2025 : Successfully completed execution
Wed Feb 12 23:56:45 UTC 2025 : Method completed with status: 204
```

------
#### [ Proxy integration ]

```
Wed Feb 12 23:59:42 UTC 2025 : Starting execution for request: abcd-1234-5678
Wed Feb 12 23:59:42 UTC 2025 : HTTP Method: GET, Resource Path: /pets
Wed Feb 12 23:59:42 UTC 2025 : Method request path: {}
Wed Feb 12 23:59:42 UTC 2025 : Method request query string: {}
Wed Feb 12 23:59:42 UTC 2025 : Method request headers: {x-version=beta}
Wed Feb 12 23:59:42 UTC 2025 : Method request body before transformations: 
Wed Feb 12 23:59:42 UTC 2025 : Endpoint request URI: http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:59:42 UTC 2025 : Endpoint request headers: { x-version=beta}
Wed Feb 12 23:59:42 UTC 2025 : Endpoint request body after transformations: 
Wed Feb 12 23:59:42 UTC 2025 : Sending request to http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:59:43 UTC 2025 : Received response. Status: 204, Integration latency: 123 ms
Wed Feb 12 23:59:43 UTC 2025 : Endpoint response headers: {Date=Wed, 12 Feb 2025 23:59:43 GMT}
Wed Feb 12 23:59:43 UTC 2025 : Endpoint response body before transformations: 
Wed Feb 12 23:59:43 UTC 2025 : Method response body after transformations:
Wed Feb 12 23:59:43 UTC 2025 : Method response headers: {Date=Wed, 12 Feb 2025 23:59:43 GMT}
Wed Feb 12 23:59:43 UTC 2025 : Successfully completed execution
Wed Feb 12 23:59:43 UTC 2025 : Method completed with status: 204
```

------

To import a similar API and test it in the Amazon Web Services Management Console, see the [example API](api-gateway-create-api-from-example.md).

## Additional REST API features for development


API Gateway supports additional features for the development of your REST API. For example, to help your customers understand your API, you can provide documentation for the API. To enable this, add a [DocumentationPart](https://docs.amazonaws.cn/apigateway/latest/api/API_DocumentationPart.html) resource for a supported API entity.

To control how clients call an API, use [IAM permissions](permissions.md), a [Lambda authorizer](apigateway-use-lambda-authorizer.md), or an [Amazon Cognito user pool](apigateway-integrate-with-cognito.md). To meter the use of your API, set up [usage plans](api-gateway-api-usage-plans.md) to throttle API requests. You can enable these when creating or updating your API.

The following diagram shows the features available for REST API development and where in the request/response model these features are configured.

For an introduction on how to create an API, see [Tutorial: Create a REST API with a Lambda proxy integration](api-gateway-create-api-as-simple-proxy-for-lambda.md). To learn more information about the capabilities of API Gateway that you might use while developing a REST API, see the following topics. These topics contain conceptual information and procedures that you can perform using the API Gateway console, the API Gateway REST API, the Amazon CLI, or one of the Amazon SDKs.

**Topics**
+ [

## Example resource for a REST API
](#rest-api-develop-example)
+ [

## Additional REST API features for development
](#rest-api-develop-details)
+ [

# API endpoint types for REST APIs in API Gateway
](api-gateway-api-endpoint-types.md)
+ [

# Security policies for REST APIs in API Gateway
](apigateway-security-policies.md)
+ [

# IP address types for REST APIs in API Gateway
](api-gateway-ip-address-type.md)
+ [

# Methods for REST APIs in API Gateway
](how-to-method-settings.md)
+ [

# Control and manage access to REST APIs in API Gateway
](apigateway-control-access-to-api.md)
+ [

# Integrations for REST APIs in API Gateway
](how-to-integration-settings.md)
+ [

# Request validation for REST APIs in API Gateway
](api-gateway-method-request-validation.md)
+ [

# Data transformations for REST APIs in API Gateway
](rest-api-data-transformations.md)
+ [

# Gateway responses for REST APIs in API Gateway
](api-gateway-gatewayResponse-definition.md)
+ [

# CORS for REST APIs in API Gateway
](how-to-cors.md)
+ [

# Binary media types for REST APIs in API Gateway
](api-gateway-payload-encodings.md)
+ [

# Invoke REST APIs in API Gateway
](how-to-call-api.md)
+ [

# Develop REST APIs using OpenAPI in API Gateway
](api-gateway-import-api.md)

# API endpoint types for REST APIs in API Gateway
API Gateway endpoint types

An *[API endpoint](api-gateway-basic-concept.md#apigateway-definition-api-endpoints)* type refers to the hostname of the API. The API endpoint type can be *edge-optimized*, *Regional*, or *private*, depending on where the majority of your API traffic originates from.

## Edge-optimized API endpoints


An *[edge-optimized API endpoint](api-gateway-basic-concept.md#apigateway-definition-edge-optimized-api-endpoint)* typically routes requests to the nearest CloudFront Point of Presence (POP), which could help in cases where your clients are geographically distributed. This is the default endpoint type for API Gateway REST APIs.

Edge-optimized APIs capitalize the names of [HTTP headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) (for example, `Cookie`).

CloudFront sorts HTTP cookies in natural order by cookie name before forwarding the request to your origin. For more information about the way CloudFront processes cookies, see [Caching Content Based on Cookies](https://docs.amazonaws.cn/AmazonCloudFront/latest/DeveloperGuide/Cookies.html).

Any custom domain name that you use for an edge-optimized API applies across all regions.

## Regional API endpoints


A *[Regional API endpoint](api-gateway-basic-concept.md#apigateway-definition-regional-api-endpoint)* is intended for clients in the same Region. When a client running on an EC2 instance calls an API in the same Region, or when an API is intended to serve a small number of clients with high demands, a Regional API reduces connection overhead.

For a Regional API, any custom domain name that you use is specific to the Region where the API is deployed. If you deploy a Regional API in multiple Regions, it can have the same custom domain name in all Regions. You can use custom domains together with Amazon Route 53 to perform tasks such as [latency-based routing](https://docs.amazonaws.cn/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-latency). For more information, see [Set up a Regional custom domain name in API Gateway](apigateway-regional-api-custom-domain-create.md) and [Set up an edge-optimized custom domain name in API Gateway](how-to-edge-optimized-custom-domain-name.md).

Regional API endpoints pass all header names through as-is.

**Note**  
In cases where API clients are geographically dispersed, it may still make sense to use a Regional API endpoint, together with your own Amazon CloudFront distribution to ensure that API Gateway does not associate the API with service-controlled CloudFront distributions. For more information about this use case, see [How do I set up API Gateway with my own CloudFront distribution?](https://repost.aws/knowledge-center/api-gateway-cloudfront-distribution).

## Private API endpoints


A *[private API endpoint](api-gateway-basic-concept.md#apigateway-definition-private-api-endpoint)* is an API endpoint that can only be accessed from your Amazon Virtual Private Cloud (VPC) using an interface VPC endpoint, which is an endpoint network interface (ENI) that you create in your VPC. For more information, see [Private REST APIs in API Gateway](apigateway-private-apis.md).

Private API endpoints pass all header names through as-is.

# Change a public or private API endpoint type in API Gateway
Change a public or private API endpoint type

Changing an API endpoint type requires you to update the API's configuration. You can change an existing API type using the API Gateway console, the Amazon CLI, or an Amazon SDK for API Gateway. The endpoint type cannot be changed again until the current change is completed, but your API will be available. 

The following endpoint type changes are supported:
+ From edge-optimized to Regional or private
+ From Regional to edge-optimized or private
+ From private to Regional

You cannot change a private API into an edge-optimized API.

If you are changing a public API from edge-optimized to Regional or vice versa, note that an edge-optimized API may have different behaviors than a Regional API. For example, an edge-optimized API removes the `Content-MD5` header. Any MD5 hash value passed to the backend can be expressed in a request string parameter or a body property. However, the Regional API passes this header through, although it may remap the header name to some other name. Understanding the differences helps you decide how to update an edge-optimized API to a Regional one or from a Regional API to an edge-optimized one. 

**Topics**
+ [

## Use the API Gateway console to change an API endpoint type
](#migrate-api-using-console)
+ [

## Use the Amazon CLI to change an API endpoint type
](#migrate-api-using-aws-cli)

## Use the API Gateway console to change an API endpoint type


To change the API endpoint type of your API, perform one of the following sets of steps:

**To convert a public endpoint from Regional or edge-optimized and vice versa**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose **API settings**.

1. In the **API details** section, choose **Edit**.

1. For **API endpoint type**, select either **Edge-optimized** or **Regional**.

1. Choose **Save changes**.

1. Redeploy your API so that the changes will take effect.

**To convert a private endpoint to a Regional endpoint**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Edit the resource policy for your API to remove any mention of VPCs or VPC endpoints so that API calls from outside your VPC as well as inside your VPC will succeed.

1. Choose **API settings**.

1. In the **API details** section, choose **Edit**.

1. For **API endpoint type**, select **Regional**.

1. Choose **Save changes**.

1. Remove the resource policy from your API.

1. Redeploy your API so that the changes will take effect.

   Because you're migrating the endpoint type from private to Regional, API Gateway changes the IP address type to IPv4. For more information, see [IP address types for REST APIs in API Gateway](api-gateway-ip-address-type.md).

**To convert a Regional endpoint to a private endpoint**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Create a resource policy that grants access to your VPC or VPC endpoint. For more information, see [Step 3: Set up a resource policy for a private API](apigateway-private-api-create.md#apigateway-private-api-set-up-resource-policy).

1. Choose **API settings**.

1. In the **API details** section, choose **Edit**.

1. For **API endpoint type**, select **Private**.

1. (Optional) For **VPC endpoint IDs**, select the VPC endpoint IDs that you want to associate with your private API. 

1. Choose **Save changes**.

1. Redeploy your API so that the changes will take effect.

   Because you're migrating the endpoint type from Regional to private, API Gateway changes the IP address type to dualstack. For more information, see [IP address types for REST APIs in API Gateway](api-gateway-ip-address-type.md).

## Use the Amazon CLI to change an API endpoint type


The following [update-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-rest-api.html) command updates an edge-optimized API to a Regional API: 

```
aws apigateway update-rest-api \
    --rest-api-id a1b2c3 \
    --patch-operations op=replace,path=/endpointConfiguration/types/EDGE,value=REGIONAL
```

The successful response has a status code of `200 OK` and a payload similar to the following:

```
{
    "createdDate": "2017-10-16T04:09:31Z",
    "description": "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints",
    "endpointConfiguration": {
        "types": "REGIONAL"
    },
    "id": "a1b2c3",
    "name": "PetStore imported as edge-optimized"
}
```

The following [update-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-rest-api.html) command updates a Regional API to an edge-optimized API:

```
aws apigateway update-rest-api \
    --rest-api-id a1b2c3 \
    --patch-operations op=replace,path=/endpointConfiguration/types/REGIONAL,value=EDGE
```

Because [put-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-rest-api.html) is for updating API definitions, it is not applicable to updating an API endpoint type.

# Security policies for REST APIs in API Gateway
Security policies

A *security policy* is a predefined combination of minimum TLS version and cipher suites offered by API Gateway. When your clients establish a TLS handshake to your API or custom domain name, the security policy enforces the TLS version and cipher suite accepted by API Gateway. Security policies protect your APIs and custom domain names from network security problems such as tampering and eavesdropping between a client and server.

API Gateway supports legacy security policies and enhanced security policies. `TLS_1_0` and `TLS_1_2` are legacy security policies. Use these security policies for backwards compatibility. Any policy that starts with `SecurityPolicy_` is an enhanced security policy. Use these policies for regulated workloads, advanced governance, or to use post-quantum cryptography. When you use an enhanced security policy, you must also set the endpoint access mode for additional governance. For more information, see [Endpoint access mode](#apigateway-security-policies-endpoint-access-mode).

## How API Gateway applies security policies


The following example shows how API Gateway applies security policies using the `SecurityPolicy_TLS13_1_3_2025_09` security policy as an example.

The `SecurityPolicy_TLS13_1_3_2025_09` security policy accepts TLS 1.3 traffic and rejects TLS 1.2 and TLS 1.0 traffic. For TLS 1.3 traffic, the security policy accepts the following cipher suites:
+ `TLS_AES_128_GCM_SHA256`
+ `TLS_AES_256_GCM_SHA384`
+ `TLS_CHACHA20_POLY1305_SHA256`

API Gateway does not accept any other cipher suites. For instance, the security policy would reject any TLS 1.3 traffic that uses the `AES128-SHA` cipher suite. For more information about the supported TLS versions and ciphers, see [Supported security policies](apigateway-security-policies-list.md).

To monitor which TLS protocol and ciphers clients used to access your API Gateway, you can use the `$context.tlsVersion` and `$context.cipherSuite` context variables in your access logs. For more information, see [Monitor REST APIs in API Gateway](rest-api-monitor.md).

## Endpoint access mode


Endpoint access mode is an additional parameter that you must specify for any REST API or custom domain name that uses an enhanced security policy that begins with `SecurityPolicy_`. You do this when you create your resource or if you change the security policy from a legacy policy to an enhanced policy.

When the endpoint access mode is set to `STRICT`, any requests to your REST API or custom domain name must pass the following checks:
+ The request must originate from the same API Gateway endpoint type as your resource. This could be from a Regional, an edge-optimized, or a private endpoint.
+ If you use a Regional or private endpoint, API Gateway uses SNI host matching. If you use an edge-optimized endpoint, API Gateway conforms to CloudFront's domain fronting protection. For more information, see [Domain fronting](https://docs.amazonaws.cn/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-restrictions).

If either of these conditions are not met, API Gateway rejects the request. We recommend that you use `STRICT` endpoint access mode when possible.

To migrate an existing API or domain name to use strict endpoint access mode, first update your security policy to an enhanced security policy and keep the endpoint access mode set to `BASIC`. After you validate your traffic and access logs, set the endpoint access mode to `STRICT`. When you migrate the endpoint access mode from `STRICT` to `BASIC`, your endpoint will be unavailable for around 15 minutes as the changes propagate.

You should not set the endpoint access mode to `STRICT` for certain application architectures and instead set the endpoint access mode to `BASIC`. The following table shows some application architectures and a recommendation so your REST API or custom domain name can use `STRICT` endpoint access mode.


| Architecture | Suggested migration | 
| --- | --- | 
| Using a VPC endpoint to access a public custom domain name. | This architecture uses cross-endpoint type traffic. We recommend that you migrate to [Custom domain names for private APIs in API Gateway](apigateway-private-custom-domains.md). | 
|  Using any method to invoke a private API that doesn't use a custom domain name or private DNS names. | This architecture creates a mismatch between the host header and the SNI used in the TLS handshake and does not pass CloudFront's domain fronting restrictions. We recommend you migrate your VPC to use private DNS. | 
| Using domain sharding to distribute content across multiple domains or subdomains. | This architecture creates a mismatch between the host header and the SNI used in the TLS handshake and does not pass CloudFront's domain fronting restrictions. We recommend that you use `HTTP/2` and migrate away from this anti-pattern. | 

The following are considerations for using endpoint access mode:
+ If the endpoint access mode of an API or domain name is `STRICT`, you can't change the endpoint type. To change the endpoint type, first change the endpoint access mode to `BASIC`.
+ After you change the endpoint access mode from `BASIC` to `STRICT`, there is a 15 minute delay for API Gateway to enforce the strict endpoint access mode.
+ When you change a security policy from a policy that begins with `SecurityPolicy_` to a legacy policy, you must unset the endpoint access mode to `""`.

## Considerations


The following are considerations for security policies for REST APIs in API Gateway:
+ You can import the security policy in an OpenAPI definition file. For more information, see [x-amazon-apigateway-endpoint-access-modex-amazon-apigateway-security-policy](openapi-extensions-security-policy.md).
+ Your API can be mapped to a custom domain name with a different security policy than your API. When you invoke that custom domain name, API Gateway uses the security policy of the API to negotiate the TLS handshake. If you disable your default API endpoint, this might affect how callers can invoke your API.
+ If you change your security policy, it takes about 15 minutes for the update to complete. You can monitor the `apiStatus` of your API. As your API updates, the `apiStatus` is `UPDATING` and when it completes, it will be `AVAILABLE`. When your API status is `UPDATING`, you can still invoke it.
+ API Gateway supports security policies on all APIs. However, you can only choose a security policy for REST APIs. API Gateway only supports the `TLS_1_2` security policy for HTTP or WebSocket APIs.
+ You can't update the security policy for an API from `TLS_1_0` to `TLS_1_2`.
+ Some security policies support both ECDSA and RSA cipher suites. If you use this type of policy with a custom domain name, the cipher suites match the customer-provided certificate key type, either RSA or ECDSA. If you use this type of policy with a REST API, the cipher suites match the cipher suites compatible with RSA certificate types.

# Supported security policies


The following tables describe the [security policies](apigateway-security-policies.md) that can be specified for each REST API endpoint type and custom domain name type. These policies allow you to control incoming connections. API Gateway only supports TLS 1.2 on egress. You can update the security policy for your API or custom domain name at any time.

Policies that contain `FIPS` in the title are compatible with the Federal Information Processing Standard (FIPS), which is a US and Canadian government standard that specifies the security requirements for cryptographic modules that protect sensitive information. To learn more, see [Federal Information Processing Standard (FIPS) 140](https://www.amazonaws.cn/compliance/fips/) on the *Amazon Cloud Security Compliance* page.

All FIPS policies leverage the AWS-LC FIPS validated cryptographic module. To learn more, see the [ AWS-LC Cryptographic Module](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4631) page on the *NIST Cryptographic Module Validation Program* site.

Policies that contain `PQ` in the title use [Post-Quantum Cryptography (PQC)](https://aws.amazon.com/security/post-quantum-cryptography/) to implement hybrid key exchange algorithms for TLS to ensure traffic confidentiality against future quantum computing threats.

Policies that contain `PFS` in the title use [Perfect Forward Secrecy (PFS)](https://en.wikipedia.org/wiki/Forward_secrecy) to make sure session keys aren't compromised.

Policies that contain both `FIPS` and `PQ` in their title support both of these features.

## Default security policies


When you create a new REST API or custom domain, the resource is assigned a default security policy. The following table shows the default security policy for these resources.


| **Resource** | **Default security policy name** | 
| --- | --- | 
| Regional APIs | TLS\$11\$10 | 
| Edge-optimized APIs | TLS\$11\$10 | 
| Private APIs | TLS\$11\$12 | 
| Regional domain | TLS\$11\$12 | 
| Edge-optimized domain | TLS\$11\$12 | 
| Private domain | TLS\$11\$12 | 

## Supported security policies for Regional and private APIs and custom domain names


The following table describes the security policies that can be specified for Regional and private APIs and custom domain names:


| **Security policy** | **Supported TLS versions** | **Supported ciphers** | 
| --- | --- | --- | 
| SecurityPolicy\$1TLS13\$11\$13\$12025\$109 | TLS1.3 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$13\$1FIPS\$12025\$109 | TLS1.3 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$1FIPS\$1PFS\$1PQ\$12025\$109 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$1PFS\$1PQ\$12025\$109 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$1PQ\$12025\$109 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$12021\$106 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| TLS\$11\$12 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| TLS\$11\$10 |  TLS1.3 TLS1.2 TLS1.1 TLS1.0  |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 

## Supported security policies for edge-optimized APIs and custom domain names


The following table describes the security policies that can be specified for edge-optimized APIs and edge-optimized custom domain names:


| **Security policy name** | **Supported TLS versions** | **Supported ciphers** | 
| --- | --- | --- | 
| SecurityPolicy\$1TLS13\$12025\$1EDGE | TLS1.3 |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS12\$1PFS\$12025\$1EDGE |  TLS1.3 TLS1.2  |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS12\$12018\$1EDGE |  TLS1.3 TLS1.2  |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| TLS\$11\$10 |  TLS1.3 TLS1.2 TLS1.1 TLS1.0  |  [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 

## OpenSSL and RFC cipher names


OpenSSL and IETF RFC 5246 use different names for the same ciphers. The following table maps the OpenSSL name to the RFC name for each cipher. For more information, see [ciphers](https://docs.openssl.org/1.1.1/man1/ciphers/) in the OpenSSL Documentation.


| **OpenSSL cipher name** | **RFC cipher name** | 
| --- | --- | 
| TLS\$1AES\$1128\$1GCM\$1SHA256 | TLS\$1AES\$1128\$1GCM\$1SHA256 | 
| TLS\$1AES\$1256\$1GCM\$1SHA384 | TLS\$1AES\$1256\$1GCM\$1SHA384 | 
| TLS\$1CHACHA20\$1POLY1305\$1SHA256 | TLS\$1CHACHA20\$1POLY1305\$1SHA256 | 
| ECDHE-RSA-AES128-GCM-SHA256 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 | 
| ECDHE-RSA-AES128-SHA256 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256  | 
| ECDHE-RSA-AES128-SHA | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA | 
| ECDHE-RSA-AES256-GCM-SHA384 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384  | 
| ECDHE-RSA-AES256-SHA384 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA384  | 
| ECDHE-RSA-AES256-SHA | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA | 
| AES128-GCM-SHA256 | TLS\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 | 
| AES256-GCM-SHA384 | TLS\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 | 
| AES128-SHA256 | TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 | 
| AES256-SHA | TLS\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA | 
| AES128-SHA | TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA | 
| DES-CBC3-SHA | TLS\$1RSA\$1WITH\$13DES\$1EDE\$1CBC\$1SHA | 

# How to change a security policy


You can change the security policy for your API. If you are sending traffic to your APIs through your custom domain name, the API and the custom domain name don't need to have the same security policy. When you invoke that custom domain name, API Gateway uses the security policy of the API to negotiate the TLS handshake. However, for consistency, we recommend that you use the same security policy for your custom domain name and API.

If you change your security policy, it takes about 15 minutes for the update to complete. You can monitor the `apiStatus` of your API. As your API updates, the `apiStatus` is `UPDATING` and when it completes, it will be `AVAILABLE`. When your API is updating, you can still invoke it.

------
#### [ Amazon Web Services Management Console ]

**To change the security policy of an API**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose **API settings**, and then choose **Edit**.

1. For **Security policy**, select a new policy that starts with `SecurityPolicy_`.

1. For **Endpoint access mode**, choose **Strict**.

1. Choose **Save changes**.

   Redeploy your API for the changes to take effect. Because you changed the endpoint access mode to strict, it will take about 15 minutes for the changes to fully propagate.

------
#### [ Amazon CLI ]

The following [update-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-rest-api.html) command updates an API to use the `SecurityPolicy_TLS13_1_3_2025_09` security policy:

```
aws apigateway update-rest-api \
    --rest-api-id abcd1234 \
    --patch-operations '[
        {
            "op": "replace",
            "path": "/securityPolicy",
            "value": "SecurityPolicy_TLS13_1_3_2025_09"
        }, 
        {
            "op": "replace",
            "path": "/endpointAccessMode",
            "value": "STRICT"
        }
    ]'
```

The output will look like the following:

```
{
    "id": "abcd1234",
    "name": "MyAPI",
    "description": "My API with a new security policy",
    "createdDate": "2025-02-04T11:47:06-08:00",
    "apiKeySource": "HEADER",
    "endpointConfiguration": {
        "types": [
            "REGIONAL"
        ],
        "ipAddressType": "dualstack"
    },
    "tags": {},
    "disableExecuteApiEndpoint": false,
    "securityPolicy": "SecurityPolicy_TLS13_1_3_2025_09",
    "endpointAccessMode": "STRICT"
    "rootResourceId": "efg456"
}
```

The following [update-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-rest-api.html) command updates a API that was using an enhanced security policy to use the `TLS_1_0` security policy.

```
aws apigateway update-rest-api \
    --rest-api-id abcd1234 \
    --patch-operations '[
        {
            "op": "replace",
            "path": "/securityPolicy",
            "value": "TLS_1_0"
        }, 
        {
            "op": "replace",
            "path": "/endpointAccessMode",
            "value": ""
        }
    ]'
```

The output will look like the following:

```
{
    "id": "abcd1234",
    "name": "MyAPI",
    "description": "My API with a new security policy",
    "createdDate": "2025-02-04T11:47:06-08:00",
    "apiKeySource": "HEADER",
    "endpointConfiguration": {
        "types": [
            "REGIONAL"
        ],
        "ipAddressType": "dualstack"
    },
    "tags": {},
    "disableExecuteApiEndpoint": false,
    "securityPolicy": "TLS_1_0",
    "rootResourceId": "efg456"
}
```

------

# IP address types for REST APIs in API Gateway


When you create an API, you specify the type of IP addresses that can invoke your API. You can choose IPv4 to resolve IPv4 addresses to invoke your API, or you can choose dualstack to allow both IPv4 and IPv6 addresses to invoke your API. We recommend that you set the IP address type to dualstack to alleviate IP space exhaustion or for your security posture. For more information about the benefits of a dualstack IP address type, see [IPv6 on Amazon](https://docs.amazonaws.cn/whitepapers/latest/ipv6-on-aws/internet-protocol-version-6.html).

To restrict your API to only IPv6 traffic, you can create a resource policy and restrict the source IP addresses to only IPv6 ranges. You can change the IP address type by updating the API’s configuration. This change will take effect immediately, and you don't need to redeploy your API. For more information, see [Example: Deny API traffic based on source IP address or range](apigateway-resource-policies-examples.md#apigateway-resource-policies-source-ip-address-example)

## Considerations for IP address types


The following considerations might impact your use of IP address types:
+ The default IP address type for all Regional and edge-optimized APIs is IPv4.
+ Private APIs can only have a dualstack IP address type.
+ If you change the IP address type for an existing API from IPv4 to dualstack, confirm that any policies controlling access to your APIs have been updated to account for IPv6 calls. When you change the IP address type, the change takes effect immediately. 
+ If you migrate the endpoint type of an API from Regional or edge-optimized to private, API Gateway changes the IP address type to dualstack. For more information, see [Change a public or private API endpoint type in API Gateway](apigateway-api-migration.md).
+ If you migrate the endpoint type of an API from private to Regional, you must set the IP address type to dualstack. After the endpoint migration is complete, you can change the IP address type to IPv4. For more information, see [Change a public or private API endpoint type in API Gateway](apigateway-api-migration.md).
+ Your API can be mapped to a custom domain name with a different IP address type than your API. If you disable your default API endpoint, this might affect how callers can invoke your API.
+ You can't use an external definition file to configure your API's IP address type.

# Change the IP address type of a REST API


You can change the IP address type by updating the API’s configuration. You can update the API's configuration by using the Amazon Web Services Management Console, the Amazon CLI, Amazon CloudFormation, or an Amazon SDK. If you change the API’s IP address type, you don't redeploy your API for the changes to take effect. Before you change the IP address type, confirm that any policies controlling access to your APIs have been updated to account for IPv6 calls.

------
#### [ Amazon Web Services Management Console ]

**To change the IP address type of a REST API**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose **API settings**, and then choose **Edit**.

1. For IP address type, select either **IPv4** or **Dualstack**.

1. Choose **Save changes**.

   The change to your API's configuration will take effect immediately.

------
#### [ Amazon CLI ]

The following [update-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-rest-api.html) command updates an API to have an IP address type of dualstack:

```
aws apigateway update-rest-api \
    --rest-api-id abcd1234 \
    --patch-operations "op='replace',path='/endpointConfiguration/ipAddressType',value='dualstack'"
```

The output will look like the following:

```
{
    "id": "abcd1234",
    "name": "MyAPI",
    "description": "My API with a dualstack IP address type",
    "createdDate": "2025-02-04T11:47:06-08:00",
    "apiKeySource": "HEADER",
    "endpointConfiguration": {
        "types": [
            "REGIONAL"
        ],
        "ipAddressType": "dualstack"
    },
    "tags": {},
    "disableExecuteApiEndpoint": false,
    "rootResourceId": "efg456"
}
```

------

# Methods for REST APIs in API Gateway
Methods

 In API Gateway, an API method embodies a [method request](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html) and a [method response](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html). You set up an API method to define what a client should or must do to submit a request to access the service at the backend and to define the responses that the client receives in return. For input, you can choose method request parameters, or an applicable payload, for the client to provide the required or optional data at run time. For output, you determine the method response status code, headers, and applicable body as targets to map the backend response data into, before they are returned to the client. To help the client developer understand the behaviors and the input and output formats of your API, you can [document your API](api-gateway-documenting-api.md) and [provide proper error messages](api-gateway-gatewayResponse-definition.md#customize-gateway-responses) for [invalid requests](api-gateway-method-request-validation.md). 

An API method request is an HTTP request. To set up the method request, you configure an HTTP method (or verb), the path to an API [resource](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html), headers, applicable query string parameters. You also configure a payload when the HTTP method is `POST`, `PUT`, or `PATCH`. For example, to retrieve a pet using the [PetStore sample API](api-gateway-create-api-from-example.md), you define the API method request of `GET /pets/{petId}`, where `{petId}` is a path parameter that can take a number at run time.

```
GET /pets/1
Host: apigateway.us-east-1.amazonaws.com
...
```

If the client specifies an incorrect path, for example, `/pet/1` or `/pets/one` instead of `/pets/1`, an exception is thrown.

An API method response is an HTTP response with a given status code. For a non-proxy integration, you must set up method responses to specify the required or optional targets of mappings. These transform integration response headers or body to associated method response headers or body. The mapping can be as simple as an [identity transform](https://en.wikipedia.org/wiki/Identity_transform) that passes the headers or body through the integration as-is. For example, the following `200` method response shows an example of passthrough of a successful integration response as-is.

```
200 OK 
Content-Type: application/json
...

{
    "id": "1",
    "type": "dog",
    "price": "$249.99"
}
```

In principle, you can define a method response corresponding to a specific response from the backend. Typically, this involves any 2XX, 4XX, and 5XX responses. However, this may not be practical, because often you may not know in advance all the responses that a backend may return. In practice, you can designate one method response as the default to handle the unknown or unmapped responses from the backend. It is good practice to designate the 500 response as the default. In any case, you must set up at least one method response for non-proxy integrations. Otherwise, API Gateway returns a 500 error response to the client even when the request succeeds at the backend.

 To support a strongly typed SDK, such as a Java SDK, for your API, you should define the data model for input for the method request, and define the data model for output of the method response. 

## Prerequisites


Before setting up an API method, verify the following:
+ You must have the method available in API Gateway. Follow the instructions in [Tutorial: Create a REST API with an HTTP non-proxy integration](api-gateway-create-api-step-by-step.md).
+ If you want the method to communicate with a Lambda function, you must have already created the Lambda invocation role and Lambda execution role in IAM. You must also have created the Lambda function with which your method will communicate in Amazon Lambda. To create the roles and function, use the instructions in [Create a Lambda function for Lambda non-proxy integration](getting-started-lambda-non-proxy-integration.md#getting-started-new-lambda) of the [Choose an Amazon Lambda integration tutorial](getting-started-with-lambda-integration.md). 
+ If you want the method to communicate with an HTTP or HTTP proxy integration, you must have already created, and have access to, the HTTP endpoint URL with which your method will communicate.
+  Verify that your certificates for HTTP and HTTP proxy endpoints are supported by API Gateway. For details see [API Gateway-supported certificate authorities for HTTP and HTTP proxy integrations in API Gateway](api-gateway-supported-certificate-authorities-for-http-endpoints.md). 

**Topics**
+ [

## Prerequisites
](#method-setting-prerequisites)
+ [

# Set up a method request in API Gateway
](api-gateway-method-settings-method-request.md)
+ [

# Set up a method response in API Gateway
](api-gateway-method-settings-method-response.md)
+ [

# Set up a method using the API Gateway console
](how-to-set-up-method-using-console.md)

# Set up a method request in API Gateway
Set up method request

Setting up a method request involves performing the following tasks, after creating a [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource:

1.  Creating a new API or choosing an existing API [Resource](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html) entity. 

1.  Creating an API [Method](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html) resource that is a specific HTTP verb on the new or chosen API `Resource`. This task can be further divided into the following sub tasks:
   +  Adding an HTTP method to the method request
   +  Configuring request parameters
   +  Defining a model for the request body
   +  Enacting an authorization scheme
   +  Enabling request validation 

You can perform these tasks using the following methods: 
+  [API Gateway console](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console)
+  Amazon CLI commands ([create-resource](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-resource.html) and [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html))
+  Amazon SDK functions (for example, in Node.js, [createResource](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#createResource-property) and [putMethod](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#putMethod-property))
+  API Gateway REST API ([resource:create](https://docs.amazonaws.cn/apigateway/latest/api/API_CreateResource.html) and [method:put](https://docs.amazonaws.cn/apigateway/latest/api/API_PutMethod.html)).

**Topics**
+ [

## Set up API resources
](#setup-method-resources)
+ [

## Set up an HTTP method
](#setup-method-add-http-method)
+ [

## Set up method request parameters
](#setup-method-request-parameters)
+ [

## Set up a method request model
](#setup-method-request-model)
+ [

## Set up method request authorization
](#setup-method-request-authorization)
+ [

## Set up method request validation
](#setup-method-request-validation)

## Set up API resources


In an API Gateway API, you expose addressable resources as a tree of API [Resources](https://docs.amazonaws.cn/apigateway/latest/api/API_GetResources.html) entities, with the root resource (`/`) at the top of the hierarchy. The root resource is relative to the API's base URL, which consists of the API endpoint and a stage name. In the API Gateway console, this base URI is referred to as the **Invoke URI** and is displayed in the API's stage editor after the API is deployed. 

The API endpoint can be a default host name or a custom domain name. The default host name is of the following format:

```
{api-id}.execute-api.{region}.amazonaws.com
```

In this format, the *\$1api-id\$1* represents the API identifier that is generated by API Gateway. The `{region}` variable represents the Amazon Region (for example, `us-east-1`) that you chose when creating the API. A custom domain name is any user-friendly name under a valid internet domain. For example, if you have registered an internet domain of `example.com`, any of `*.example.com` is a valid custom domain name. For more information, see [create a custom domain name](how-to-custom-domains.md). 

For the [PetStore sample API](api-gateway-create-api-from-example.md), the root resource (`/`) exposes the pet store. The `/pets` resource represents the collection of pets available in the pet store. The `/pets/{petId}` exposes an individual pet of a given identifier (`petId`). The path parameter of `{petId}` is part of the request parameters. 

To set up an API resource, you choose an existing resource as its parent and then create the child resource under this parent resource. You start with the root resource as a parent, add a resource to this parent, add another resource to this child resource as the new parent, and so on, to its parent identifier. Then you add the named resource to the parent. 

The following [get-resources](https://docs.amazonaws.cn/cli/latest/reference/apigateway/get-resources.html) command retrieves all the resources of an API:

```
aws apigateway get-resources --rest-api-id apiId
```

For the PetStore sample API, the output looks like the following:

```
{
    "items": [
        {
            "path": "/pets", 
            "resourceMethods": {
                "GET": {}
            }, 
            "id": "6sxz2j", 
            "pathPart": "pets", 
            "parentId": "svzr2028x8"
        }, 
        {
            "path": "/pets/{petId}", 
            "resourceMethods": {
                "GET": {}
            }, 
            "id": "rjkmth", 
            "pathPart": "{petId}", 
            "parentId": "6sxz2j"
        }, 
        {
            "path": "/", 
            "id": "svzr2028x8"
        }
    ]
}
```

Each item lists the identifiers of the resource (`id`) and, except for the root resource, its immediate parent (`parentId`), as well as the resource name (`pathPart`). The root resource is special in that it does not have any parent. After choosing a resource as the parent, use the following command to add a child resource: 

```
aws apigateway create-resource --rest-api-id apiId \
    --parent-id parentId \
    --path-part resourceName
```

For example, to add pet food for sale on the PetStore website, use the following command:

```
aws apigateway create-resource --rest-api-id a1b2c3 \
    --parent-id svzr2028x8 \
    --path-part food
```

The output will look like the following:

```
{
    "path": "/food", 
    "pathPart": "food", 
    "id": "xdsvhp", 
    "parentId": "svzr2028x8"
}
```

### Use a proxy resource to streamline API setup


As business grows, the PetStore owner may decide to add food, toys, and other pet-related items for sale. To support this, you can add `/food`, `/toys`, and other resources under the root resource. Under each sale category, you may also want to add more resources, such as `/food/{type}/{item}`, `/toys/{type}/{item}`, etc. This can get tedious. If you decide to add a middle layer `{subtype}` to the resource paths to change the path hierarchy into `/food/{type}/{subtype}/{item}`, `/toys/{type}/{subtype}/{item}`, etc., the changes will break the existing API set up. To avoid this, you can use an API Gateway [proxy resource](api-gateway-set-up-simple-proxy.md) to expose a set of API resources all at once.

API Gateway defines a proxy resource as a placeholder for a resource to be specified when the request is submitted. A proxy resource is expressed by a special path parameter of `{proxy+}`, often referred to as a greedy path parameter. The `+` sign indicates whichever child resources are appended to it. The `/parent/{proxy+}` placeholder stands for any resource matching the path pattern of `/parent/*`. You can use any string for the greedy path parameter name.

The following [create-resource](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-resource.html) command creates a proxy resource under the root (`/{proxy+}`):

```
aws apigateway create-resource --rest-api-id apiId \
    --parent-id rootResourceId \
    --path-part {proxy+}
```

The output will look like the following: 

```
{
    "path": "/{proxy+}", 
    "pathPart": "{proxy+}", 
    "id": "234jdr", 
    "parentId": "svzr2028x8"
}
```

For the `PetStore` API example, you can use `/{proxy+}` to represent both the `/pets` and `/pets/{petId}`. This proxy resource can also reference any other (existing or to-be-added) resources, such as `/food/{type}/{item}`, `/toys/{type}/{item}`, etc., or `/food/{type}/{subtype}/{item}`, `/toys/{type}/{subtype}/{item}`, etc. The backend developer determines the resource hierarchy and the client developer is responsible for understanding it. API Gateway simply passes whatever the client submitted to the backend. 

An API can have more than one proxy resource. For example, the following proxy resources are allowed within an API, assuming `/parent/{proxy+}` is not the same parent as `/parent/{child}/{proxy+}`.

```
/{proxy+}
/parent/{proxy+}
/parent/{child}/{proxy+}
```

When a proxy resource has non-proxy siblings, the sibling resources are excluded from the representation of the proxy resource. For the preceding examples, `/{proxy+}` refers to any resources under the root resource except for the `/parent[/*]` resources. In other words, a method request against a specific resource takes precedence over a method request against a generic resource at the same level of the resource hierarchy.

The following table shows how API Gateway routes requests to the following resources for the `prod` stage of an API.

```
ANY /{proxy+}
GET /pets/{proxy+}
GET /pets/dog
```


| Request | Selected route | Explanation | 
| --- | --- | --- | 
|  `GET https://api-id.execute-api.region.amazonaws.com/prod/pets/dog`  |  `GET /pets/dog`  |  The request fully matches this resource.  | 
|  `GET https://api-id.execute-api.region.amazonaws.com/prod/pets/cats`  |  `GET /pets/{proxy+}`  |  The `/pets/{proxy+}` greedy path variable catches this request.  | 
|  `GET https://api-id.execute-api.region.amazonaws.com/prod/animals`  |  `GET /{proxy+}`  |  The `/{proxy+}` greedy path variable catches this request.  | 

A proxy resource cannot have any child resource. Any API resource after `{proxy+}` is redundant and ambiguous. The following proxy resources are not allowed within an API.

```
/{proxy+}/child
/parent/{proxy+}/{child}
/parent/{child}/{proxy+}/{grandchild+}
```

## Set up an HTTP method


An API method request is encapsulated by the API Gateway [Method](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html) resource. To set up the method request, you must first instantiate the `Method` resource, setting at least an HTTP method and an authorization type on the method. 

Closely associated with the proxy resource, API Gateway supports an HTTP method of `ANY`. This `ANY` method represents any HTTP method that is to be supplied at run time. It allows you to use a single API method setup for all of the supported HTTP methods of `DELETE`, `GET`, `HEAD`, `OPTIONS`, `PATCH`, `POST`, and `PUT`. 

You can set up the `ANY` method on a non-proxy resource as well. Combining the `ANY` method with a proxy resource, you get a single API method setup for all of the supported HTTP methods against any resources of an API. Furthermore, the backend can evolve without breaking the existing API setup. 

 Before setting up an API method, consider who can call the method. Set the authorization type according to your plan. For open access, set it to `NONE`. To use IAM permissions, set the authorization type to `AWS_IAM`. To use a Lambda authorizer function, set this property to `CUSTOM`. To use an Amazon Cognito user pool, set the authorization type to `COGNITO_USER_POOLS`. 

The following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command creates a method request for the `ANY` verb using IAM permissions to control its access. 

```
aws apigateway put-method --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method ANY \
    --authorization-type AWS_IAM
```

To create an API method request with a different authorization type, see [Set up method request authorization](#setup-method-request-authorization).

## Set up method request parameters


Method request parameters are a way for a client to provide input data or execution context necessary to complete the method request. A method parameter can be a path parameter, a header, or a query string parameter. As part of method request setup, you must declare required request parameters to make them available for the client. For non-proxy integration, you can translate these request parameters to a form that is compatible with the backend requirement. 

For example, for the `GET /pets/{petId}` method request, the `{petId}` path variable is a required request parameter. You can declare this path parameter when calling the `put-method` command of the Amazon CLI. The following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command creates a method with a required path parameter:

```
aws apigateway put-method --rest-api-id vaz7da96z6 \
    --resource-id rjkmth \
    --http-method GET \
    --authorization-type "NONE" \
    --request-parameters method.request.path.petId=true
```

If a parameter is not required, you can set it to `false` in `request-parameters`. For example, if the `GET /pets` method uses an optional query string parameter of `type`, and an optional header parameter of `age`, you can declare them using the following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command:

```
aws apigateway put-method --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method GET \
    --authorization-type "NONE" \
    --request-parameters method.request.querystring.type=false,method.request.header.age=false
```

Instead of this abbreviated form, you can use a JSON string to set the `request-parameters` value:

```
'{"method.request.querystring.type":false,"method.request.header.age":false}'
```

With this setup, the client can query pets by type: 

```
GET /pets?type=dog
```

 And the client can query dogs who are puppies as follows:

```
GET /pets?type=dog
age:puppy
```

For information on how to map method request parameters to integration request parameters, see [Integrations for REST APIs in API Gateway](how-to-integration-settings.md).

## Set up a method request model


For an API method that can take input data in a payload, you can use a model. A model is expressed in a [JSON schema draft 4](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04) and describes the data structure of the request body. With a model, a client can determine how to construct a method request payload as input. More importantly, API Gateway uses the model to [validate a request](api-gateway-method-request-validation.md), [generate an SDK](how-to-generate-sdk.md), and initialize a mapping template for setting up the integration in the API Gateway console. For information about how to create a [model](https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html), see [Understanding data models](models-mappings-models.md). 

Depending on the content types, a method payload can have different formats. A model is indexed against the media type of the applied payload. API Gateway uses the `Content-Type` request header to determine the content type. To set up method request models, add key-value pairs of the `"media-type":"model-name"` format to the `requestModels` map when calling the Amazon CLI `put-method` command. 

To use the same model regardless of the content type, specify `$default` as the key.

For example, to set a model on the JSON payload of the `POST /pets` method request of the PetStore example API, you can use the following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command:

```
aws apigateway put-method \
    --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method POST \
    --authorization-type "NONE" \
    --request-models '{"application/json":"petModel"}'
```

Here, `petModel` is the `name` property value of a [https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html](https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html) resource describing a pet. The actual schema definition is expressed as a JSON string value of the [https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html#schema](https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html#schema) property of the `Model` resource. 

 In a Java, or other strongly typed SDK, of the API, the input data is cast as the `petModel` class derived from the schema definition. With the request model, the input data in the generated SDK is cast into the `Empty` class, which is derived from the default `Empty` model. In this case, the client cannot instantiate the correct data class to provide the required input. 



## Set up method request authorization




 To control who can call the API method, you can configure the [authorization type](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#authorizationType) on the method. You can use this type to enact one of the supported authorizers, including IAM roles and policies (`AWS_IAM`), an Amazon Cognito user pool (`COGNITO_USER_POOLS`), or a Lambda authorizer (`CUSTOM`).

To use IAM permissions to authorize access to the API method, set the `authorization-type` input property to **AWS\$1IAM**. When you set this option, API Gateway verifies the caller's signature on the request based on the caller's credentials. If the verified user has permission to call the method, it accepts the request. Otherwise, it rejects the request and the caller receives an unauthorized error response. The call to the method doesn't succeed unless the caller has permission to invoke the API method. The following IAM policy grants permission to the caller to call any API methods created within the same Amazon Web Services account: 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": "arn:aws-cn:execute-api:*:*:*"
        }
    ]
}
```

------

For more information, see [Control access to a REST API with IAM permissions](permissions.md).

Currently, you can only grant this policy to the users, groups, and roles within the API owner's Amazon Web Services account. Users from a different Amazon Web Services account can call the API methods only if allowed to assume a role within the API owner's Amazon Web Services account with the necessary permissions to call the `execute-api:Invoke` action. For information on cross-account permissions, see [Using IAM Roles](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_use.html). 

You can use Amazon CLI, an Amazon SDK, or a REST API client, such as [Postman](https://www.postman.com/), which implements [Signature Version 4 (SigV4) signing](https://docs.amazonaws.cn/IAM/latest/UserGuide/create-signed-request.html). 

To use a Lambda authorizer to authorize access to the API method, set the `authorization-type` input property to `CUSTOM` and set the [https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#authorizerId](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#authorizerId) input property to the [https://docs.amazonaws.cn/apigateway/latest/api/API_Authorizer.html#id](https://docs.amazonaws.cn/apigateway/latest/api/API_Authorizer.html#id) property value of a Lambda authorizer that already exists. The referenced Lambda authorizer can be of the `TOKEN` or `REQUEST` type. For information about creating a Lambda authorizer, see [Use API Gateway Lambda authorizers](apigateway-use-lambda-authorizer.md).

To use an Amazon Cognito user pool to authorize access to the API method, set the `authorization-type` input property to `COGNITO_USER_POOLS` and set the [https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#authorizerId](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#authorizerId) input property to the [https://docs.amazonaws.cn/apigateway/latest/api/API_Authorizer.html#id](https://docs.amazonaws.cn/apigateway/latest/api/API_Authorizer.html#id) property value of the `COGNITO_USER_POOLS` authorizer that was already created. For information about creating an Amazon Cognito user pool authorizer, see [Control access to REST APIs using Amazon Cognito user pools as an authorizer](apigateway-integrate-with-cognito.md).

## Set up method request validation


You can enable request validation when setting up an API method request. You need to first create a [request validator](https://docs.amazonaws.cn/apigateway/latest/api/API_RequestValidator.html). The following [create-request-validator](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-request-validator.html) command creates a body-only request validator. 

```
aws apigateway create-request-validator \
    --rest-api-id 7zw9uyk9kl \
    --name bodyOnlyValidator \
    --validate-request-body  \
    --no-validate-request-parameters
```

The output will look like the following:

```
{
    "validateRequestParameters": false, 
    "validateRequestBody": true, 
    "id": "jgpyy6", 
    "name": "bodyOnlyValidator"
}
```

You can use this request validator, to use request validation as part of the method request setup. The following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command creates a method request that requires the incoming request body to match the `PetModel` and has two request parameter that aren't required: 

```
aws apigateway put-method \
    --rest-api-id 7zw9uyk9kl \
    --resource-id xdsvhp \
    --http-method PUT \
    --authorization-type "NONE" \
    --request-parameters '{"method.request.querystring.type": false, "method.request.querystring.page":false}' \ 
    --request-models '{"application/json":"petModel"}' \
    --request-validator-id jgpyy6
```

To include a request parameter in the request validation, you must set `validateRequestParameters` to `true` for the request validator, and set the specific request parameter to `true` in the `put-method` command.

# Set up a method response in API Gateway
Set up method response

An API method response encapsulates the output of an API method request that the client will receive. The output data includes an HTTP status code, some headers, and possibly a body. 

With non-proxy integrations, the specified response parameters and body can be mapped from the associated integration response data or can be assigned certain static values according to mappings. These mappings are specified in the integration response. The mapping can be an identical transformation that passes the integration response through as-is.

With a proxy integration, API Gateway passes the backend response through to the method response automatically. There is no need for you to set up the API method response. However, with the Lambda proxy integration, the Lambda function must return a result of [this output format](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format) for API Gateway to successfully map the integration response to a method response. 

Programmatically, the method response setup amounts to creating a [MethodResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html) resource of API Gateway and setting the properties of [statusCode](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#statusCode), [responseParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseParameters), and [responseModels](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseModels). 

When setting status codes for an API method, you should choose one as the default to handle any integration response of an unanticipated status code. It is reasonable to set `500` as the default because this amounts to casting otherwise unmapped responses as a server-side error. For instructional reasons, the API Gateway console sets the `200` response as the default. But you can reset it to the `500` response. 

To set up a method response, you must have created the method request. 

## Set up method response status code


The status code of a method response defines a type of response. For example, responses of 200, 400, and 500 indicate successful, client-side error and server-side error responses, respectively. 

To set up a method response status code, set the [https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#statusCode](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#statusCode) property to an HTTP status code. The following [put-method-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method-response.html) command creates `200` method response.

```
aws apigateway put-method-response \
    --rest-api-id vaz7da96z6 \ 
    --resource-id 6sxz2j \
    --http-method GET \
    --status-code 200
```

## Set up method response parameters


Method response parameters define which headers the client receives in response to the associated method request. Response parameters also specify a target to which API Gateway maps an integration response parameter, according to mappings prescribed in the API method's integration response. 

To set up the method response parameters, add to the [https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseParameters) map of `MethodResponse` key-value pairs of the `"{parameter-name}":"{boolean}"` format. The following [put-method-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method-response.html) command sets the `my-header` header.

```
aws apigateway put-method-response \
        --rest-api-id vaz7da96z6 \
        --resource-id 6sxz2j \
        --http-method GET \
        --status-code 200  \
        --response-parameters method.response.header.my-header=false
```

## Set up method response models


 

 A method response model defines a format of the method response body. Setting up a method response model is necessary when you generate a strongly typed SDK for the API. It ensures that the output is cast into an appropriate class in Java or Objective-C. In other cases, setting a model is optional.

Before setting up the response model, you must first create the model in API Gateway. To do so, you can call the `[create-model](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-model.html)` command. The following [create-model](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-model.html) command creates `PetStorePet` model to describe the body of the response to the `GET /pets/{petId}` method request.

```
aws apigateway create-model \
    --rest-api-id vaz7da96z6 \
    --content-type application/json \
    --name PetStorePet \
    --schema '{ \
                  "$schema": "http://json-schema.org/draft-04/schema#", \
                  "title": "PetStorePet", \
                  "type": "object", \
                  "properties": { \
                    "id": { "type": "number" }, \
                    "type": { "type": "string" }, \
                    "price": { "type": "number" } \
                  } \
              }'
```

The result is created as an API Gateway [https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html](https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html) resource.

To set up the method response models to define the payload format, add the "application/json":"PetStorePet" key-value pair to the [https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseModels](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseModels) map of [https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html) resource. The following [put-method-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method-response.html) command creates a method response that uses a response model to define the payload format: 

```
aws apigateway put-method-response \
    --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method GET \
    --status-code 200  \
    --response-parameters method.response.header.my-header=false \
    --response-models '{"application/json":"PetStorePet"}'
```

# Set up a method using the API Gateway console
Set up method using the console

When you create a method using the REST API console, you configure both the integration request and the method request. By default, API Gateway creates the `200` method response for your method.

The following instructions show how to edit the method request settings and how to create additional method responses for your method.

**Topics**
+ [

## Edit an API Gateway method request in the API Gateway console
](#how-to-method-settings-callers-console)
+ [

## Set up an API Gateway method response using the API Gateway console
](#how-to-method-response-settings-console)

## Edit an API Gateway method request in the API Gateway console
Edit a method request in the console

 These instructions assume you have already created your method request. For more information on how to create a method, see [Set up an API integration request using the API Gateway console](how-to-method-settings-console.md).

1. In the **Resources** pane, choose your method, and then choose the **Method request** tab. 

1. In the **Method request settings** section, choose **Edit**.

1. For **Authorization**, select an available authorizer. 

   1. To enable open access to the method for any user, select **None**. This step can be skipped if the default setting has not been changed.

   1. To use IAM permissions to control the client access to the method, select `AWS_IAM`. With this choice, only users of the IAM roles with the correct IAM policy attached are allowed to call this method. 

      To create the IAM role, specify an access policy with a format like the following: 

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "execute-api:Invoke"
            ],
            "Resource": [
              "arn:aws-cn:execute-api:us-east-1:111111111111:aaabbb/*/GET/"
            ]
          }
        ]
      }
      ```

------

      In this access policy, `arn:aws:execute-api:us-east-1:111111111111:aaabbb/*/GET/` is the ARN of your method. You can find the ARN of your method by selecting the method on the **Resources** page. For more information about setting the IAM permissions, see [Control access to a REST API with IAM permissions](permissions.md). 

      To create the IAM role, you can adapt the instructions in the following tutorial, [Create a Lambda function for Lambda non-proxy integration](getting-started-lambda-non-proxy-integration.md#getting-started-new-lambda). 

   1.  To use a Lambda authorizer, select a token or a request authorizer. Create the Lambda authorizer to have this choice displayed in the dropdown menu. For information on how to create a Lambda authorizer, see [Use API Gateway Lambda authorizers](apigateway-use-lambda-authorizer.md). 

   1.  To use an Amazon Cognito user pool, choose an available user pool under **Cognito user pool authorizers**. Create a user pool in Amazon Cognito and an Amazon Cognito user pool authorizer in API Gateway to have this choice displayed in the dropdown menu. For information on how to create an Amazon Cognito user pool authorizer, see [Control access to REST APIs using Amazon Cognito user pools as an authorizer](apigateway-integrate-with-cognito.md). 

1.  To specify request validation, select a value from the **Request Validator** dropdown menu. To turn off request validation, select **None**. For more information about each option, see [Request validation for REST APIs in API Gateway](api-gateway-method-request-validation.md). 

1. Select **API key required** to require an API key. When enabled, API keys are used in [usage plans](api-gateway-api-usage-plans.md) to throttle client traffic. 

1. (Optional) To assign an operation name in a Java SDK of this API, generated by API Gateway, for **Operation name**, enter a name. For example, for the method request of `GET /pets/{petId}`, the corresponding Java SDK operation name is, by default ,`GetPetsPetId`. This name is constructed from the method's HTTP verb (`GET`) and the resource path variable names (`Pets` and `PetId`). If you set the operation name as `getPetById`, the SDK operation name becomes `GetPetById`.

1. To add a query string parameter to the method, do the following:

   1. Choose **URL Query string parameters**, and then choose **Add query string**.

   1. For **Name**, enter the name of the query string parameter.

   1. Select **Required** if the newly created query string parameter is to be used for request validation. For more information about the request validation, see [Request validation for REST APIs in API Gateway](api-gateway-method-request-validation.md).

   1. Select **Caching** if the newly created query string parameter is to be used as part of a caching key. For more information about caching, see [Use method or integration parameters as cache keys to index cached responses](api-gateway-caching.md#enable-api-gateway-cache-keys).

   To remove the query string parameter, choose **Remove**. 

1. To add a header parameter to the method, do the following:

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

   1. For **Name**, enter the name of the header.

   1. Select **Required** if the newly created header is to be used for request validation. For more information about the request validation, see [Request validation for REST APIs in API Gateway](api-gateway-method-request-validation.md).

   1. Select **Caching** if the newly created header is to be used as part of a caching key. For more information about caching, see [Use method or integration parameters as cache keys to index cached responses](api-gateway-caching.md#enable-api-gateway-cache-keys).

   To remove the header, choose **Remove**. 

1.  To declare the payload format of a method request with the `POST`, `PUT`, or `PATCH` HTTP verb, choose **Request body**, and do the following: 

   1. Choose **Add model**.

   1. For **Content-type**, enter a MIME-type (for example, `application/json`).

   1. For **Model**, select a model from the dropdown menu. The currently available models for the API include the default `Empty` and `Error` models as well as any models you have created and added to the [Models](https://docs.amazonaws.cn/apigateway/latest/api/API_Model.html) collection of the API. For more information about creating a model, see [Data models for REST APIs](models-mappings-models.md). 
**Note**  
 The model is useful to inform the client of the expected data format of a payload. It is helpful to generate a skeletal mapping template. It is important to generate a strongly typed SDK of the API in such languages as Java, C\$1, Objective-C, and Swift. It is only required if request validation is enabled against the payload. 

1. Choose **Save**.

## Set up an API Gateway method response using the API Gateway console
Set up a method response using the console

 An API method can have one or more responses. Each response is indexed by its HTTP status code. By default, the API Gateway console adds `200` response to the method responses. You can modify it, for example, to have the method return `201` instead. You can add other responses, for example, `409` for access denial and `500` for uninitialized stage variables used. 

 To use the API Gateway console to modify, delete, or add a response to an API method, follow these instructions.

1. In the **Resources** pane, choose your method, and then choose the **Method response** tab. You might need to choose the right arrow button to show the tab.

1. In the **Method response settings** section, choose **Create response**.

1. For **HTTP status code**, enter an HTTP status code such as `200`, `400`, or `500`.

    When a backend-returned response does not have a corresponding method response defined, API Gateway fails to return the response to the client. Instead, it returns a `500 Internal server error` error response. 

1. Choose **Add header**.

1.  For **Header name**, enter a name.

    To return a header from the backend to the client, add the header in the method response. 

1.  Choose **Add model** to define a format of the method response body.

   Enter the media type of the response payload for **Content type** and choose a model from the **Models** dropdown menu.

1. Choose **Save**.

To modify an existing response, navigate to your method response, and then choose **Edit**. To change the **HTTP status code**, choose **Delete** and create a new method response.

For every response returned from the backend, you must have a compatible response configured as the method response. However, the configuring method response headers and payload model are optional unless you map the result from the backend to the method response before returning to the client. Also, a method response payload model is important if you are generating a strongly typed SDK for your API.

# Control and manage access to REST APIs in API Gateway
Access control

API Gateway supports multiple mechanisms for controlling and managing access to your API.

You can use the following mechanisms for authentication and authorization:
+ **Resource policies** let you create resource-based policies to allow or deny access to your APIs and methods from specified source IP addresses or VPC endpoints. For more information, see [Control access to a REST API with API Gateway resource policies](apigateway-resource-policies.md).
+ **Standard Amazon IAM roles and policies** offer flexible and robust access controls that can be applied to an entire API or individual methods. IAM roles and policies can be used for controlling who can create and manage your APIs, as well as who can invoke them. For more information, see [Control access to a REST API with IAM permissions](permissions.md).
+ **IAM tags** can be used together with IAM policies to control access. For more information, see [Using tags to control access to API Gateway REST API resources](apigateway-tagging-iam-policy.md).
+ **Endpoint policies for interface VPC endpoints** allow you to attach IAM resource policies to interface VPC endpoints to improve the security of your [private APIs](https://docs.amazonaws.cn/apigateway/latest/developerguide/apigateway-private-apis.html). For more information, see [Use VPC endpoint policies for private APIs in API Gateway](apigateway-vpc-endpoint-policies.md).
+ **Lambda authorizers** are Lambda functions that control access to REST API methods using bearer token authentication—as well as information described by headers, paths, query strings, stage variables, or context variables request parameters. Lambda authorizers are used to control who can invoke REST API methods. For more information, see [Use API Gateway Lambda authorizers](apigateway-use-lambda-authorizer.md).
+ **Amazon Cognito user pools** let you create customizable authentication and authorization solutions for your REST APIs. Amazon Cognito user pools are used to control who can invoke REST API methods. For more information, see [Control access to REST APIs using Amazon Cognito user pools as an authorizer](apigateway-integrate-with-cognito.md).

You can use the following mechanisms for performing other tasks related to access control:
+ **Cross-origin resource sharing (CORS)** lets you control how your REST API responds to cross-domain resource requests. For more information, see [CORS for REST APIs in API Gateway](how-to-cors.md).
+ **Client-side SSL certificates** can be used to verify that HTTP requests to your backend system are from API Gateway. For more information, see [Generate and configure an SSL certificate for backend authentication in API Gateway](getting-started-client-side-ssl-authentication.md).
+ **Amazon WAF** can be used to protect your API Gateway API from common web exploits. For more information, see [Use Amazon WAF to protect your REST APIs in API Gateway](apigateway-control-access-aws-waf.md).

You can use the following mechanisms for tracking and limiting the access that you have granted to authorized clients:
+ **Usage plans** let you provide **API keys** to your customers—and then track and limit usage of your API stages and methods for each API key. For more information, see [Usage plans and API keys for REST APIs in API Gateway](api-gateway-api-usage-plans.md).

# Control access to a REST API with API Gateway resource policies
Use API Gateway resource policies

Amazon API Gateway *resource policies* are JSON policy documents that you attach to an API to control whether a specified principal (typically an IAM role or group) can invoke the API. You can use API Gateway resource policies to allow your API to be securely invoked by:
+ Users from a specified Amazon account.
+ Specified source IP address ranges or CIDR blocks.
+ Specified virtual private clouds (VPCs) or VPC endpoints (in any account).

You can attach a resource policy for any API endpoint type in API Gateway by using the Amazon Web Services Management Console, Amazon CLI, or Amazon SDKs. For [private APIs](https://docs.amazonaws.cn/apigateway/latest/developerguide/apigateway-private-apis.html), you can use resource policies together with VPC endpoint policies to control which principals have access to which resources and actions. For more information, see [Use VPC endpoint policies for private APIs in API Gateway](apigateway-vpc-endpoint-policies.md).

 API Gateway resource policies are different from IAM identity-based policies. IAM identity-based policies are attached to IAM users, groups, or roles and define what actions those identities are capable of doing on which resources. API Gateway resource policies are attached to resources. You can use API Gateway resource policies together with IAM policies. For more information, see [Identity-Based Policies and Resource-Based Policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_identity-vs-resource.html).

**Topics**
+ [

# Access policy language overview for Amazon API Gateway
](apigateway-control-access-policy-language-overview.md)
+ [

# How API Gateway resource policies affect authorization workflow
](apigateway-authorization-flow.md)
+ [

# API Gateway resource policy examples
](apigateway-resource-policies-examples.md)
+ [

# Create and attach an API Gateway resource policy to an API
](apigateway-resource-policies-create-attach.md)
+ [

# Amazon condition keys that can be used in API Gateway resource policies
](apigateway-resource-policies-aws-condition-keys.md)

# Access policy language overview for Amazon API Gateway


This page describes the basic elements used in Amazon API Gateway resource policies.

Resource policies are specified using the same syntax as IAM policies. For complete policy language information, see [ Overview of IAM Policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies.html) and [Amazon Identity and Access Management Policy Reference](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies.html) in the *IAM User Guide*.

For information about how an Amazon service decides whether a given request should be allowed or denied, see [Determining Whether a Request is Allowed or Denied](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow).

## Common elements in an access policy


In its most basic sense, a resource policy contains the following elements:
+ **Resources** – APIs are the Amazon API Gateway resources for which you can allow or deny permissions. In a policy, you use the Amazon Resource Name (ARN) to identify the resource. You can also use abbreviated syntax, which API Gateway automatically expands to the full ARN when you save a resource policy. To learn more, see [API Gateway resource policy examples](apigateway-resource-policies-examples.md).

  For the format of the full `Resource` element, see [Resource format of permissions for executing API in API Gateway](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-iam-policy-resource-format-for-executing-api).
+ **Actions** – For each resource, Amazon API Gateway supports a set of operations. You identify resource operations that you will allow (or deny) by using action keywords.

  For example, the `execute-api:Invoke` permission will allow the user permission to invoke an API upon a client request.

  For the format of the `Action` element, see [Action format of permissions for executing API in API Gateway](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-iam-policy-action-format-for-executing-api).
+ **Effect** – What the effect is when the user requests the specific action—this can be either `Allow` or `Deny`. You can also explicitly deny access to a resource, which you might do in order to make sure that a user cannot access it, even if a different policy grants access. 
**Note**  
"Implicit deny" is the same thing as "deny by default".  
An "implicit deny" is different from an "explicit deny". For more information, see [The Difference Between Denying by Default and Explicit Deny](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#AccessPolicyLanguage_Interplay).
+ **Principal** – The account or user allowed access to the actions and resources in the statement. In a resource policy, the principal is the user or account who receives this permission.

The following example resource policy shows the previous common policy elements. The policy grants access to the API under the specified *account-id* in the specified *region* to any user whose source IP address is in the address block *123.4.5.6/24*. The policy denies all access to the API if the user's source IP is not within the range.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws-cn:execute-api:us-east-1:111111111111:*"
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws-cn:execute-api:us-east-1:111111111111:*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "123.4.5.6/24"
                }
            }
        }
    ]
}
```

------

# How API Gateway resource policies affect authorization workflow
How resource policies affect authorization workflow

When API Gateway evaluates the resource policy attached to your API, the result is affected by the authentication type that you have defined for the API, as illustrated in the flowcharts in the following sections.

**Topics**
+ [

## API Gateway resource policy only
](#apigateway-authorization-flow-resource-policy-only)
+ [

## Lambda authorizer and resource policy
](#apigateway-authorization-flow-lambda)
+ [

## IAM authentication and resource policy
](#apigateway-authorization-flow-iam)
+ [

## Amazon Cognito authentication and resource policy
](#apigateway-authorization-flow-cognito)
+ [

## Policy evaluation outcome tables
](#apigateway-resource-policies-iam-policies-interaction)

## API Gateway resource policy only


In this workflow, an API Gateway resource policy is attached to the API, but no authentication type is defined for the API. Evaluation of the policy involves seeking an explicit allow based on the inbound criteria of the caller. An implicit denial or any explicit denial results in denying the caller.

The following is an example of such a resource policy.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws-cn:execute-api:us-east-1:111111111111:api-id/",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}
```

------

## Lambda authorizer and resource policy


In this workflow, a Lambda authorizer is configured for the API in addition to a resource policy. The resource policy is evaluated in two phases. Before calling the Lambda authorizer, API Gateway first evaluates the policy and checks for any explicit denials. If found, the caller is denied access immediately. Otherwise, the Lambda authorizer is called, and it returns a [policy document](api-gateway-lambda-authorizer-output.md), which is evaluated in conjunction with the resource policy. If your authorizer uses caching, API Gateway might return the cached policy document. The result is determined based on [Table A](#apigateway-resource-policies-iam-policies-interaction).

The following example resource policy allows calls only from the VPC endpoint whose VPC endpoint ID is `vpce-1a2b3c4d`. During the "pre-auth" evaluation, only the calls coming from the VPC endpoint indicated in the example are allowed to move forward and evaluate the Lambda authorizer. All remaining calls are blocked. This authorization workflow is the same if you use a custom domain name for a private API.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws-cn:execute-api:us-east-1:111111111111:api-id/"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-1a2b3c4d"
                }
            }
        }
    ]
}
```

------

## IAM authentication and resource policy


In this workflow, you configure IAM authentication for the API in addition to a resource policy. After you authenticate the user with the IAM service, the API evaluates both the policies attached to the user and the resource policy. The outcome varies based on whether the caller is in the same Amazon Web Services account or a separate Amazon Web Services account, from the API owner. 

If the caller and API owner are from separate accounts, both the IAM policies and the resource policy explicitly allow the caller to proceed. For more information, see [Table B](#apigateway-resource-policies-iam-policies-interaction). 

However, if the caller and the API owner are in the same Amazon Web Services account, then either the IAM user policies or the resource policy must explicitly allow the caller to proceed. For more information, see [Table A](#apigateway-resource-policies-iam-policies-interaction).

The following is an example of a cross-account resource policy. Assuming the IAM policy contains an allow effect, this resource policy allows calls only from the VPC whose VPC ID is `vpc-2f09a348`. For more information, see [Table B](#apigateway-resource-policies-iam-policies-interaction).

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws-cn:execute-api:us-east-1:111111111111:api-id/"
            ],
            "Condition" : {
                "StringEquals": {
                    "aws:SourceVpc": "vpc-2f09a348"
                    }
            }
        }
    ]
}
```

------

## Amazon Cognito authentication and resource policy


In this workflow, an [Amazon Cognito user pool](apigateway-integrate-with-cognito.md) is configured for the API in addition to a resource policy. API Gateway first attempts to authenticate the caller through Amazon Cognito. This is typically performed through a [JWT token](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html) that is provided by the caller. If authentication is successful, the resource policy is evaluated independently, and an explicit allow is required. A deny or "neither allow or deny" results in a deny. The following is an example of a resource policy that might be used together with Amazon Cognito user pools.

The following is an example of a resource policy that allows calls only from specified source IPs, assuming that the Amazon Cognito authentication token contains an allow. For more information, see [Table B](#apigateway-resource-policies-iam-policies-interaction).

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws-cn:execute-api:us-east-1:111111111111:api-id/",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}
```

------

## Policy evaluation outcome tables


Table A lists the resulting behavior when access to an API Gateway API is controlled by an IAM policy or a Lambda authorizer and an API Gateway resource policy, both of which are in the same Amazon Web Services account.


| **IAM policy (or Lambda authorizer)** | **API Gateway resource policy** | **Resulting behavior** | 
| --- | --- | --- | 
| Allow | Allow | Allow | 
| Allow | Neither Allow nor Deny | Allow | 
| Allow | Deny | Explicit Deny | 
| Neither Allow nor Deny | Allow | Allow | 
| Neither Allow nor Deny | Neither Allow nor Deny | Implicit Deny | 
| Neither Allow nor Deny | Deny | Explicit Deny | 
| Deny | Allow | Explicit Deny | 
| Deny | Neither Allow nor Deny | Explicit Deny | 
| Deny | Deny | Explicit Deny | 

Table B lists the resulting behavior when access to an API Gateway API is controlled by an IAM policy or a Amazon Cognito user pools authorizer and an API Gateway resource policy, which are in different Amazon Web Services accounts. If either is silent (neither allow nor deny), cross-account access is denied. This is because cross-account access requires that both the resource policy and the IAM policy or Amazon Cognito user pools authorizer explicitly grant access.


| **IAM policy (or Amazon Cognito user pools authorizer)** | **API Gateway resource policy** | **Resulting behavior** | 
| --- | --- | --- | 
| Allow | Allow | Allow | 
| Allow | Neither Allow nor Deny | Implicit Deny | 
| Allow | Deny | Explicit Deny | 
| Neither Allow nor Deny | Allow | Implicit Deny | 
| Neither Allow nor Deny | Neither Allow nor Deny | Implicit Deny | 
| Neither Allow nor Deny | Deny | Explicit Deny | 
| Deny | Allow | Explicit Deny | 
| Deny | Neither Allow nor Deny | Explicit Deny | 
| Deny | Deny | Explicit Deny | 

# API Gateway resource policy examples


This page presents a few examples of typical use cases for API Gateway resource policies.

The following example policies use a simplified syntax to specify the API resource. This simplified syntax is an abbreviated way that you can refer to an API resource, instead of specifying the full Amazon Resource Name (ARN). API Gateway converts the abbreviated syntax to the full ARN when you save the policy. For example, you can specify the resource `execute-api:/stage-name/GET/pets` in a resource policy. API Gateway converts the resource to `arn:aws:execute-api:us-west-2:123456789012:aabbccddee/stage-name/GET/pets` when you save the resource policy. API Gateway builds the full ARN by using the current Region, your Amazon account ID, and the ID of the REST API that the resource policy is associated with. You can use `execute-api:/*` to represent all stages, methods, and paths in the current API. For information about access policy language, see [Access policy language overview for Amazon API Gateway](apigateway-control-access-policy-language-overview.md).

**Topics**
+ [

## Example: Allow roles in another Amazon account to use an API
](#apigateway-resource-policies-cross-account-example)
+ [

## Example: Deny API traffic based on source IP address or range
](#apigateway-resource-policies-source-ip-address-example)
+ [

## Example: Deny API traffic based on source IP address or range when using a private API
](#apigateway-resource-policies-source-ip-address-vpc-example)
+ [

## Example: Allow private API traffic based on source VPC or VPC endpoint
](#apigateway-resource-policies-source-vpc-example)

## Example: Allow roles in another Amazon account to use an API


The following example resource policy grants API access in one Amazon account to two roles in a different Amazon account via [Signature Version 4](https://docs.amazonaws.cn/IAM/latest/UserGuide/create-signed-request.html) (SigV4) or [Signature Version 4a](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_sigv.html#how-sigv4a-works) (SigV4a) protocols. Specifically, the developer and the administrator role for the Amazon account identified by `account-id-2` are granted the `execute-api:Invoke` action to execute the `GET` action on the `pets` resource (API) in your Amazon account.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws-cn:iam::111122223333:role/developer",
                    "arn:aws-cn:iam::111122223333:role/Admin"
                ]
            },
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/stage/GET/pets"
            ]
        }
    ]
}
```

------

## Example: Deny API traffic based on source IP address or range


The following example resource policy denies (blocks) incoming traffic to an API from two specified source IP address blocks.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
               "execute-api:/*"
            ],
            "Condition" : {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}
```

------

If you use any IAM user policies or API Gateway resource policies to control access to API Gateway or any API Gateway APIs, confirm that your policies are updated to include IPv6 address ranges. Policies that aren’t updated to handle IPv6 addresses might impact client’s access to API Gateway when they start using the dualstack endpoint. For more information, see [Using IPv6 addresses in IAM policies](api-ref.md#api-reference-service-endpoints-dualstack-iam).

## Example: Deny API traffic based on source IP address or range when using a private API


The following example resource policy denies (blocks) incoming traffic to a private API from two specified source IP address blocks. When using private APIs, the VPC endpoint for `execute-api` re-writes the original source IP address. The `aws:VpcSourceIp` condition filters the request against the original requester IP address.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
               "execute-api:/*"
            ],
            "Condition" : {
                "IpAddress": {
                    "aws:VpcSourceIp": ["192.0.2.0/24", "198.51.100.0/24"]
                }
            }
        }
    ]
}
```

------

## Example: Allow private API traffic based on source VPC or VPC endpoint


The following example resource policies allow incoming traffic to a private API only from a specified virtual private cloud (VPC) or VPC endpoint.

This example resource policy specifies a source VPC:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                   "aws:SourceVpc": "vpc-1a2b3c4d"
                }
            }
        }
    ]
}
```

------

This example resource policy specifies a source VPC endpoint:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-1a2b3c4d"
                }
            }
        }
    ]
}
```

------

# Create and attach an API Gateway resource policy to an API


To allow a user to access your API by calling the API execution service, you must create an API Gateway resource policy and attach the policy to the API. When you attach a policy to your API, it applies the permissions in the policy to the methods in the API. If you update the resource policy, you'll need to deploy the API.

**Topics**
+ [

## Prerequisites
](#apigateway-resource-policies-prerequisites)
+ [

## Attach a resource policy to an API Gateway API
](#apigateway-resource-policies-create-attach-procedure)
+ [

## Troubleshoot your resource policy
](#apigateway-resource-policies-troubleshoot)

## Prerequisites


 To update an API Gateway resource policy, you'll need the `apigateway:UpdateRestApiPolicy` permission and the `apigateway:PATCH` permission.

For an edge-optimized or Regional API, you can attach your resource policy to your API as you create it, or after it has been deployed. For a private API, you can't deploy your API without a resource policy. For more information, see [Private REST APIs in API Gateway](apigateway-private-apis.md).

## Attach a resource policy to an API Gateway API


The following procedure shows you how to attach a resource policy to an API Gateway API.

------
#### [ Amazon Web Services Management Console ]

**To attach a resource policy to an API Gateway API**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. In the main navigation pane, choose **Resource policy**.

1. Choose **Create policy**.

1. (Optional) Choose **Select a template** to generate an example policy.

   In the example policies, placeholders are enclosed in double curly braces (`"{{placeholder}}"`). Replace each of the placeholders, including the curly braces, with the necessary information.

1. If you don't use one of the template examples, enter your resource policy.

1. Choose **Save changes**.

If the API has been deployed previously in the API Gateway console, you'll need to redeploy it for the resource policy to take effect.

------
#### [ Amazon CLI ]

To use the Amazon CLI to create a new API and attach a resource policy to it, use the following [create-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-rest-api.html) command:

```
aws apigateway create-rest-api \
    --name "api-name" \
    --policy "{\"jsonEscapedPolicyDocument\"}"
```

To use the Amazon CLI to attach a resource policy to an existing API, use the following [update-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-rest-api.html) command: 

```
aws apigateway update-rest-api \
    --rest-api-id api-id \
    --patch-operations op=replace,path=/policy,value='"{\"jsonEscapedPolicyDocument\"}"'
```

You can also attach your resource policy as a separate `policy.json` file and including it in your [create-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-rest-api.html) command. The following [create-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-rest-api.html) command creates a new API with a resource policy:

```
aws apigateway create-rest-api \
    --name "api-name" \
    --policy file://policy.json
```

`policy.json` is an API Gateway resource policy, such as [Example: Deny API traffic based on source IP address or range](apigateway-resource-policies-examples.md#apigateway-resource-policies-source-ip-address-example).

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

You can use Amazon CloudFormation to create an API with a resource policy. The following example creates a REST API with the example resource policy, [Example: Deny API traffic based on source IP address or range](apigateway-resource-policies-examples.md#apigateway-resource-policies-source-ip-address-example). 

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: testapi
      Policy:
        Statement:
          - Action: 'execute-api:Invoke'
            Effect: Allow
            Principal: '*'
            Resource: 'execute-api:/*'
          - Action: 'execute-api:Invoke'
            Effect: Deny
            Principal: '*'
            Resource: 'execute-api:/*'
            Condition:
              IpAddress: 
                'aws:SourceIp': ["192.0.2.0/24", "198.51.100.0/24" ]
        Version: 2012-10-17		 	 	 
  Resource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'helloworld'
  MethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref Resource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: MOCK
        RequestTemplates:
          application/json: '{"statusCode": 200}'
        IntegrationResponses:
          - StatusCode: 200
            ResponseTemplates:
              application/json: '{}'
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            application/json: 'Empty'
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - MethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: test
```

------

## Troubleshoot your resource policy


The following troubleshooting guidance might help resolve issues with your resource policy.

### My API returns \$1"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:\$1\$1\$1\$1\$1\$1\$1\$1/\$1\$1\$1\$1/\$1\$1\$1\$1/"\$1


In your resource policy, if you set the Principal to an Amazon principal, such as the following:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws-cn:iam::111111111111:role/developer",
                    "arn:aws-cn:iam::111111111111:role/Admin"
                ]
            },
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/stage/GET/pets"
            ]
        }
    ]
}
```

------

You must use `AWS_IAM` authorization for every method in your API, or else your API returns the previous error message. For more instructions on how to turn on `AWS_IAM` authorization for a method, see [Methods for REST APIs in API Gateway](how-to-method-settings.md).

### My resource policy is not updating


 If you update the resource policy after the API is created, you'll need to deploy the API to propagate the changes after you've attached the updated policy. Updating or saving the policy alone won't change the runtime behavior of the API. For more information about deploying your API, see [Deploy REST APIs in API Gateway](how-to-deploy-api.md). 

### My resource policy returns the following error: Invalid policy document. Please check the policy syntax and ensure that Principals are valid.


To troubleshoot this error, we first recommend that you check the policy syntax. For more information, see [Access policy language overview for Amazon API Gateway](apigateway-control-access-policy-language-overview.md). We also recommend that you check that all the principals specified are valid and haven’t been deleted.

In addition, if your API is in an [opt-in Region](https://docs.amazonaws.cn/glossary/latest/reference/glos-chap.html?icmpid=docs_homepage_addtlrcs#optinregion), verify that all accounts in the resource policy have the Region enabled. 

# Amazon condition keys that can be used in API Gateway resource policies


The following table contains Amazon condition keys that can be used in resource policies for APIs in API Gateway for each authorization type.

For more information about Amazon condition keys, see [Amazon Global Condition Context Keys](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html).


| **Condition keys** | **Criteria** | **Needs `AuthN`?** | **Authorization type** | 
| --- | --- | --- | --- | 
| aws:CurrentTime | None | No | All | 
| aws:EpochTime | None | No | All | 
| aws:TokenIssueTime | Key is present only in requests that are signed using temporary security credentials. | Yes | IAM | 
| aws:MultiFactorAuthPresent | Key is present only in requests that are signed using temporary security credentials. | Yes | IAM | 
| aws:MultiFactorAuthAge | Key is present only if MFA is present in the requests. | Yes | IAM | 
| aws:PrincipalAccount | None | Yes | IAM | 
| aws:PrincipalArn | None | Yes | IAM | 
| aws:PrincipalOrgID | This key is included in the request context only if the principal is a member of an organization. | Yes | IAM | 
| aws:PrincipalOrgPaths | This key is included in the request context only if the principal is a member of an organization. | Yes | IAM | 
| aws:PrincipalTag | This key is included in the request context if the principal is using an IAM user with attached tags. It is included for a principal using an IAM role with attached tags or session tags. | Yes | IAM | 
| aws:PrincipalType | None | Yes | IAM | 
| aws:Referer | Key is present only if the value is provided by the caller in the HTTP header. | No | All | 
| aws:SecureTransport | None | No | All | 
| aws:SourceArn | None | No | All | 
| aws:SourceIp | None | No | All | 
| aws:SourceVpc | This key can be used only for private APIs. | No | All | 
| aws:SourceVpce | This key can be used only for private APIs. | No | All | 
| aws:VpcSourceIp | This key can be used only for private APIs. | No | All | 
| aws:UserAgent | Key is present only if the value is provided by the caller in the HTTP header. | No | All | 
| aws:userid | None | Yes | IAM | 
| aws:username | None | Yes | IAM | 

# Control access to a REST API with IAM permissions
Use IAM permissions

 You control access to your Amazon API Gateway API with [IAM permissions](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_controlling.html) by controlling access to the following two API Gateway component processes: 
+  To create, deploy, and manage an API in API Gateway, you must grant the API developer permissions to perform the required actions supported by the API management component of API Gateway. 
+  To call a deployed API or to refresh the API caching, you must grant the API caller permissions to perform required IAM actions supported by the API execution component of API Gateway. 

 The access control for the two processes involves different permissions models, explained next.

## API Gateway permissions model for creating and managing an API


 To allow an API developer to create and manage an API in API Gateway, you must [create IAM permissions policies](https://docs.amazonaws.cn/IAM/latest/UserGuide/access_policies_create.html) that allow a specified API developer to create, update, deploy, view, or delete required [API entities](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html). You attach the permissions policy to a user, role, or group. 

To provide access, add permissions to your users, groups, or roles:
+ Users managed in IAM through an identity provider:

  Create a role for identity federation. Follow the instructions in [Create a role for a third-party identity provider (federation)](https://docs.amazonaws.cn//IAM/latest/UserGuide/id_roles_create_for-idp.html) in the *IAM User Guide*.
+ IAM users:
  + Create a role that your user can assume. Follow the instructions in [Create a role for an IAM user](https://docs.amazonaws.cn//IAM/latest/UserGuide/id_roles_create_for-user.html) in the *IAM User Guide*.
  + (Not recommended) Attach a policy directly to a user or add a user to a user group. Follow the instructions in [Adding permissions to a user (console)](https://docs.amazonaws.cn//IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console) in the *IAM User Guide*.

For more information on how to use this permissions model, see [API Gateway identity-based policies](security_iam_service-with-iam.md#security_iam_service-with-iam-id-based-policies). 

## API Gateway permissions model for invoking an API


To allow an API caller to invoke the API or refresh its caching, you must create IAM policies that permit a specified API caller to invoke the API method for which user authentication is enabled. The API developer sets the method's `authorizationType` property to `AWS_IAM` to require that the caller submit the user's credentials to be authenticated. API Gateway supports Signature Version 4a (SigV4a) and Signature Version 4 (SigV4) to authenticate the user's credentials. For more information, see [Amazon Signature Version 4](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_sigv.html). Then, you attach the policy to a user, role, or group. 

In this IAM permissions policy statement, the IAM `Resource` element contains a list of deployed API methods identified by given HTTP verbs and API Gateway [resource paths](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html). The IAM `Action` element contains the required API Gateway API executing actions. These actions include `execute-api:Invoke` or `execute-api:InvalidateCache`, where `execute-api` designates the underlying API execution component of API Gateway. 

For more information on how to use this permissions model, see [Control access for invoking an API](api-gateway-control-access-using-iam-policies-to-invoke-api.md). 

 When an API is integrated with an Amazon service (for example, Amazon Lambda) in the back end, API Gateway must also have permissions to access integrated Amazon resources (for example, invoking a Lambda function) on behalf of the API caller. To grant these permissions, create an IAM role of the **Amazon service for API Gateway** type. When you create this role in the IAM Management console, this resulting role contains the following IAM trust policy that declares API Gateway as a trusted entity permitted to assume the role: 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

If you create the IAM role by calling the [create-role](https://docs.amazonaws.cn/cli/latest/reference/iam/create-role.html) command of CLI or a corresponding SDK method, you must supply the above trust policy as the input parameter of `assume-role-policy-document`. Do not attempt to create such a policy directly in the IAM Management console or calling Amazon CLI [create-policy](https://docs.amazonaws.cn/cli/latest/reference/iam/create-policy.html) command or a corresponding SDK method.

For API Gateway to call the integrated Amazon service, you must also attach to this role appropriate IAM permissions policies for calling integrated Amazon services. For example, to call a Lambda function, you must include the following IAM permissions policy in the IAM role: 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "*"
        }
    ]
}
```

------

Note that Lambda supports resource-based access policy, which combines both trust and permissions policies. When integrating an API with a Lambda function using the API Gateway console, you are not asked to set this IAM role explicitly, because the console sets the resource-based permissions on the Lambda function for you, with your consent. 

**Note**  
 To enact access control to an Amazon service, you can use either the caller-based permissions model, where a permissions policy is directly attached to the caller's user or group, or the role-based permission model, where a permissions policy is attached to an IAM role that API Gateway can assume. The permissions policies may differ in the two models. For example, the caller-based policy blocks the access while the role-based policy allows it. You can take advantage of this to require that a user access an Amazon service through an API Gateway API only. 

# Control access for invoking an API


In this section, you learn about the permissions model for controlling access to your API using IAM permissions. When IAM authorization is enabled, clients must use Signature Version 4a (SigV4a) and Signature Version 4 (SigV4) to sign their requests with Amazon credentials. For more information, see [Amazon Signature Version 4](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_sigv.html).

In this section, we show a template IAM policy statement and the policy statement reference. The policy statement reference includes the formats of `Action` and `Resource` fields related to the API execution service. Use these references to create your IAM policy statement. When you create your IAM policy statement, you might need to consider the how API Gateway resource policies affect the authorization workflow. For more information, see [How API Gateway resource policies affect authorization workflow](apigateway-authorization-flow.md).

For private APIs, you should use a combination of an API Gateway resource policy and a VPC endpoint policy. For more information, see the following topics:
+ [Control access to a REST API with API Gateway resource policies](apigateway-resource-policies.md)
+ [Use VPC endpoint policies for private APIs in API Gateway](apigateway-vpc-endpoint-policies.md)

## Control who can call an API Gateway API method with IAM policies


 To control who can or cannot call a deployed API with IAM permissions, create an IAM policy document with required permissions. A template for such a policy document is shown as follows. 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Permission",
      "Action": [
        "execute-api:Execution-operation"           
      ],
      "Resource": [
        "arn:aws-cn:execute-api:region:123456789012:api-id/stage/METHOD_HTTP_VERB/Resource-path"
      ]
    }
  ]
}
```

------

 Here, `Permission` is to be replaced by `Allow` or `Deny` depending on whether you want to grant or revoke the included permissions. `Execution-operation` is to be replaced by the operations supported by the API execution service. `METHOD_HTTP_VERB` stands for a HTTP verb supported by the specified resources. `Resource-path` is the placeholder for the URL path of a deployed API `[Resource](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html)` instance supporting the said `METHOD_HTTP_VERB`. For more information, see [Statement reference of IAM policies for executing API in API Gateway](#api-gateway-calling-api-permissions). 

**Note**  
For IAM policies to be effective, you must have enabled IAM authentication on API methods by setting `AWS_IAM` for the methods' `[authorizationType](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#authorizationType)` property. Failing to do so will make these API methods publicly accessible.

 For example, to grant a user permission to view a list of pets exposed by a specified API, but to deny the user permission to add a pet to the list, you could include the following statement in the IAM policy: 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"           
      ],
      "Resource": [
        "arn:aws-cn:execute-api:us-east-1:111111111111:api-id/*/GET/pets"
      ]
    },
    {
      "Effect": "Deny",
      "Action": [
        "execute-api:Invoke"           
      ],
      "Resource": [
        "arn:aws-cn:execute-api:us-east-1:111111111111:api-id/*/POST/pets"
      ]
    }
  ]
}
```

------

To grant a user permission to view a specific pet exposed by an API that is configured as `GET /pets/{petId}`, you could include the following statement in the IAM policy:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws-cn:execute-api:us-east-1:111122223333:api-id/*/GET/pets/a1b2"
            ]
        }
    ]
}
```

------

## Statement reference of IAM policies for executing API in API Gateway


The following information describes the Action and Resource format of IAM policy statements of access permissions for executing an API.

### Action format of permissions for executing API in API Gateway


The API-executing `Action` expression has the following general format:

```
execute-api:action
```

where *action* is an available API-executing action:
+ **\$1**, which represents all of the following actions.
+ **Invoke**, used to invoke an API upon a client request.
+ **InvalidateCache**, used to invalidate API cache upon a client request.

### Resource format of permissions for executing API in API Gateway


The API-executing `Resource` expression has the following general format:

```
arn:aws:execute-api:region:account-id:api-id/stage-name/HTTP-VERB/resource-path-specifier
```

where:
+ *region* is the Amazon region (such as **us-east-1** or **\$1** for all Amazon regions) that corresponds to the deployed API for the method.
+ *account-id* is the 12-digit Amazon account Id of the REST API owner. 
+ *api-id* is the identifier API Gateway has assigned to the API for the method.
+ *stage-name* is the name of the stage associated with the method.
+ *HTTP-VERB* is the HTTP verb for the method. It can be one of the following: GET, POST, PUT, DELETE, PATCH.
+ *resource-path-specifier* is the path to the desired method.

**Note**  
If you specify a wildcard (`*`), the `Resource` expression applies the wildcard to the rest of the expression.

Some example resource expressions include:
+ **arn:aws:execute-api:\$1:\$1:\$1** for any resource path in any stage, for any API in any Amazon region.
+ **arn:aws:execute-api:us-east-1:\$1:\$1** for any resource path in any stage, for any API in the Amazon region of `us-east-1`.
+ **arn:aws:execute-api:us-east-1:\$1:*api-id*/\$1** for any resource path in any stage, for the API with the identifier of *api-id* in the Amazon region of us-east-1.
+ **arn:aws:execute-api:us-east-1:\$1:*api-id*/`test`/\$1** for any resource path in the stage of `test`, for the API with the identifier of *api-id* in the Amazon region of us-east-1.

To learn more, see [API Gateway Amazon Resource Name (ARN) reference](arn-format-reference.md).

# IAM policy examples for API execution permissions


For permissions model and other background information, see [Control access for invoking an API](api-gateway-control-access-using-iam-policies-to-invoke-api.md).

The following policy statement gives the user permission to call any POST method along the path of `mydemoresource`, in the stage of `test`, for the API with the identifier of `a123456789`, assuming the corresponding API has been deployed to the Amazon region of us-east-1:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": [
        "arn:aws-cn:execute-api:us-east-1:*:a123456789/test/POST/my-demo-resource-path/*"
      ]
    }
  ]
}
```

------

The following example policy statement gives the user permission to call any method on the resource path of `petstorewalkthrough/pets`, in any stage, for the API with the identifier of `a123456789`, in any Amazon region where the corresponding API has been deployed:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": [
        "arn:aws-cn:execute-api:*:*:a123456789/*/*/petstorewalkthrough/pets"
      ]
    }
  ]
}
```

------

# Use VPC endpoint policies for private APIs in API Gateway
Use VPC endpoint policies for private APIs

To improve the security of your private API, you can create a VPC endpoint policy. A VPC endpoint policy is an IAM resource policy that you attach to a VPC endpoint. For more information, see [Controlling Access to Services with VPC Endpoints](https://docs.amazonaws.cn/vpc/latest/privatelink/vpc-endpoints-access.html).

You might want to create a VPC endpoint policy to do the following tasks.
+ Allow only certain organizations or resources to access your VPC endpoint and invoke your API.
+ Use a single policy and avoid session-based or role-based policies to control traffic to your API.
+ Tighten the security perimeter of your application while migrating from on premises to Amazon.

## VPC endpoint policy considerations


The following are considerations for your VPC endpoint policy:
+ The identity of the invoker is evaluated based on the `Authorization` header value. The VPC endpoint policy is evaluated first, and then API Gateway evaluates the request, based on the type of authorization configured on the method request. The following table shows how the VPC endpoint policy is evaluated based on the content of the `Authorization` header value.    
[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-vpc-endpoint-policies.html)
+ If your access control depends on using a bearer token, such as a Lambda or Amazon Cognito authorizer, you can control your security perimeter by using [properties of the resource](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resource-properties).
+  If your authorization controls use IAM authorization, you can control your security perimeter by using [properties of the resource](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resource-properties) and [ properties of the principal](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resource-principal).
+ VPC endpoint policies can be used together with API Gateway resource policies. The API Gateway resource policy specifies which principals can access the API. The endpoint policy specifies who can access the VPC and which APIs can be called from the VPC endpoint. Your private API needs a resource policy but you don't need to create a custom VPC endpoint policy.

## VPC endpoint policy examples


You can create policies for Amazon Virtual Private Cloud endpoints for Amazon API Gateway in which you can specify the following.
+ The principal that can perform actions.
+ The actions that can be performed.
+ The resources that can have actions performed on them.

This might depend on the contents of your authorization header. For more information, see [VPC endpoint policy considerations](#apigateway-vpc-endpoint-policies-considerations). For additional example policies, see [Data perimeter policy examples](https://github.com/aws-samples/data-perimeter-policy-examples) on the GitHub website.

To attach the policy to the VPC endpoint, you'll need to use the VPC console. For more information, see [Controlling Access to Services with VPC Endpoints](https://docs.amazonaws.cn/vpc/latest/privatelink/vpc-endpoints-access.html). 

## Example 1: VPC endpoint policy granting access to two APIs


The following example policy grants access to only two specific APIs via the VPC endpoint that the policy is attached to.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Principal": "*",
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws-cn:execute-api:us-east-1:123412341234:a1b2c3d4e5/*",
                "arn:aws-cn:execute-api:us-east-1:123412341234:aaaaa11111/*"
            ]
        }
    ]
}
```

------

## Example 2: VPC endpoint policy granting access to GET methods


The following example policy grants users access to `GET` methods for a specific API via the VPC endpoint that the policy is attached to.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Principal": "*",
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws-cn:execute-api:us-east-1:123412341234:a1b2c3d4e5/stageName/GET/*"
            ]
        }
    ]
}
```

------

## Example 3: VPC endpoint policy granting a specific user access to a specific API


The following example policy grants a specific user access to a specific API via the VPC endpoint that the policy is attached to.

In this case, because the policy restricts access to specific IAM principals, you must set the `authorizationType` of the method to `AWS_IAM` or `NONE`.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Principal": {
                "AWS": [
                    "arn:aws-cn:iam::123412341234:user/MyUser"
                ]
            },
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws-cn:execute-api:us-east-1:123412341234:a1b2c3d4e5/*"
            ]
        }
    ]
}
```

------

## Example 4: VPC endpoint policy granting users access to a specific custom domain name and every API mapped to the domain


The following example policy grants users access to a specific custom domain name for private APIs via the VPC endpoint that the policy is attached to. With this policy, as long as a user has created a domain name access association between the VPC endpoint and the custom domain name and is granted access to invoke the custom domain name and any private API's mapped to the custom domain name, the user can invoke any APIs mapped to this custom domain name. For more information, see [Custom domain names for private APIs in API Gateway](apigateway-private-custom-domains.md).

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "*"
      ],
       "Condition": {
        "ArnEquals": {
          "execute-api:viaDomainArn": "arn:aws-cn:execute-api:us-west-2:111122223333:/domainnames/private.test.com+f4g5h6",
        }
      }
    }
  ]
}
```

------

## Example 5: VPC endpoint policy granting or denying access to specific APIs and domain resources


The following example policy grants users access to specific APIs and domain resources. With this policy, as long as a user has created a domain name access association between the VPC endpoint and the custom domain name and is granted access to invoke the custom domain name and any private API's mapped to the custom domain name, the user can invoke allowed private APIs and domain resources. For more information, see [Custom domain names for private APIs in API Gateway](apigateway-private-custom-domains.md).

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "arn:aws-cn:execute-api:us-west-2:111122223333:/domainnames/private.test.com+f4g5h6",
        "arn:aws-cn:execute-api:us-west-2:111122223333:a1b2c3d4e5/*"
      ]
    },
    {
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "arn:aws-cn:execute-api:us-west-2:111122223333:a1b2c3d4e5/admin/*",
        "arn:aws-cn:execute-api:us-west-2:111122223333:bcd123455/*"
      ]
    }
  ]
}
```

------

## Example 6: VPC endpoint policy granting or denying access by principals and resources belonging to an organization


The following example policy grants access to principals and resources that belong to an organization.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceOrgID": "o-abcd1234",
                    "aws:PrincipalOrgID": "o-abcd1234"
                }
            },
            "Action": "*",
            "Resource": "*",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Sid": "AllowRequestsByOrgsIdentitiesToOrgsResources"
        }
    ]
}
```

------

# Use tags to control access to REST APIs in API Gateway
Using tags to control access to a REST API

Permission to access REST APIs can be fine-tuned using attribute-based access control in IAM policies.

For more information, see [Using tags to control access to API Gateway REST API resources](apigateway-tagging-iam-policy.md).

# Use API Gateway Lambda authorizers
Use Lambda authorizers

Use a *Lambda authorizer* (formerly known as a *custom authorizer*) to control access to your API. When a client makes a request to your API's method, API Gateway calls your Lambda authorizer. The Lambda authorizer takes the caller's identity as the input and returns an IAM policy as the output.

Use a Lambda authorizer to implement a custom authorization scheme. Your scheme can use request parameters to determine the caller's identity or use a bearer token authentication strategy such as OAuth or SAML. Create a Lambda authorizer in the API Gateway REST API console, using the Amazon CLI, or an Amazon SDK.

## Lambda authorizer authorization workflow


The following diagram shows the authorization workflow for a Lambda authorizer.

**API Gateway Lambda authorization workflow**

1. The client calls a method on an API Gateway API, passing a bearer token or request parameters.

1. API Gateway checks if the method request is configured with a Lambda authorizer. If it is, API Gateway calls the Lambda function.

1. The Lambda function authenticates the caller. The function can authenticate in the following ways:
   + By calling out to an OAuth provider to get an OAuth access token.
   + By calling out to a SAML provider to get a SAML assertion.
   + By generating an IAM policy based on the request parameter values.
   + By retrieving credentials from a database.

1. The Lambda function returns an IAM policy and a principal identifier. If the Lambda function does not return that information, the call fails. 

1. API Gateway evaluates the IAM policy.
   + If access is denied, API Gateway returns a suitable HTTP status code, such as `403 ACCESS_DENIED`.
   + If access is allowed, API Gateway invokes the method. 

     If you enable authorization caching, API Gateway caches the policy so that the Lambda authorizer function isn’t invoked again. Ensure that your policy is applicable to all resources and methods across your API.

You can customize the `403 ACCESS_DENIED` or the `401 UNAUTHORIZED` gateway responses. To learn more, see [Gateway responses for REST APIs in API Gateway](api-gateway-gatewayResponse-definition.md).

## Choosing a type of Lambda authorizer
Choosing a type of Lambda authorizer

There are two types of Lambda authorizers:

**Request parameter-based Lambda authorizer (`REQUEST` authorizer)**  
A `REQUEST` authorizer receives the caller's identity in a combination of headers, query string parameters, [`stageVariables`](api-gateway-mapping-template-reference.md#stagevariables-template-reference), and [`$context`](api-gateway-mapping-template-reference.md#context-variable-reference) variables. You can use a `REQUEST` authorizer to create fine-grained policies based on the information from multiple identity sources, such as the `$context.path` and `$context.httpMethod` context variables.  
If you turn on authorization caching for a `REQUEST` authorizer, API Gateway verifies that all specified identity sources are present in the request. If a specified identify source is missing, null, or empty, API Gateway returns a `401 Unauthorized` HTTP response without calling the Lambda authorizer function. When multiple identity sources are defined, they are all used to derive the authorizer's cache key, with the order preserved. You can define a fine-grained cache key by using multiple identity sources.  
If you change any of the cache key parts, and redeploy your API, the authorizer discards the cached policy document and generates a new one.  
If you turn off authorization caching for a `REQUEST` authorizer, API Gateway directly passes the request to the Lambda function. 

**Token-based Lambda authorizer (`TOKEN` authorizer)**  
A `TOKEN` authorizer receives the caller's identity in a bearer token, such as a JSON Web Token (JWT) or an OAuth token.  
If you turn on authorization caching for a `TOKEN` authorizer, the header name specified in the token source becomes the cache key.   
Additionally, you can use token validation to enter a RegEx statement. API Gateway performs initial validation of the input token against this expression and invokes the Lambda authorizer function upon successful validation. This helps reduce calls to your API.   
The `IdentityValidationExpression` property is supported for `TOKEN` authorizers only. For more information, see [x-amazon-apigateway-authorizer object](api-gateway-swagger-extensions-authorizer.md).

**Note**  
We recommend that you use a `REQUEST` authorizer to control access to your API. You can control access to your API based on multiple identity sources when using a `REQUEST` authorizer, compared to a single identity source when using a `TOKEN` authorizer. In addition, you can separate cache keys using multiple identity sources for a `REQUEST` authorizer.

## Example `REQUEST` authorizer Lambda function


The following example code creates a Lambda authorizer function that allows a request if the client-supplied `HeaderAuth1` header, `QueryString1` query parameter, and stage variable of `StageVar1` all match the specified values of `headerValue1`, `queryValue1`, and `stageValue1`, respectively. 

------
#### [ Node.js ]

```
// A simple request-based authorizer example to demonstrate how to use request 
// parameters to allow or deny a request. In this example, a request is  
// authorized if the client-supplied HeaderAuth1 header, QueryString1
// query parameter, and stage variable of StageVar1 all match
// specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
// respectively.
    
export const handler = function(event, context, callback) {
    console.log('Received event:', JSON.stringify(event, null, 2));
    
    // Retrieve request parameters from the Lambda function input:
    var headers = event.headers;
    var queryStringParameters = event.queryStringParameters;
    var pathParameters = event.pathParameters;
    var stageVariables = event.stageVariables;
        
    // Parse the input for the parameter values
    var tmp = event.methodArn.split(':');
    var apiGatewayArnTmp = tmp[5].split('/');
    var awsAccountId = tmp[4];
    var region = tmp[3];
    var restApiId = apiGatewayArnTmp[0];
    var stage = apiGatewayArnTmp[1];
    var method = apiGatewayArnTmp[2];
    var resource = '/'; // root resource
    if (apiGatewayArnTmp[3]) {
        resource += apiGatewayArnTmp[3];
    }
        
    // Perform authorization to return the Allow policy for correct parameters and 
    // the 'Unauthorized' error, otherwise.

     
    if (headers.HeaderAuth1 === "headerValue1"
        && queryStringParameters.QueryString1 === "queryValue1"
        && stageVariables.StageVar1 === "stageValue1") {
        callback(null, generateAllow('me', event.methodArn));
    }  else {
        callback(null, generateDeny('me', event.methodArn));
    }
}
     
// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    // Required output:
    var authResponse = {};
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
     
var generateAllow = function(principalId, resource) {
    return generatePolicy(principalId, 'Allow', resource);
}
     
var generateDeny = function(principalId, resource) {
    return generatePolicy(principalId, 'Deny', resource);
}
```

------
#### [ Python ]

```
# A simple request-based authorizer example to demonstrate how to use request
# parameters to allow or deny a request. In this example, a request is
# authorized if the client-supplied headerauth1 header, QueryString1
# query parameter, and stage variable of StageVar1 all match
# specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
# respectively.

def lambda_handler(event, context):
    print(event)

    # Retrieve request parameters from the Lambda function input:
    headers = event['headers']
    queryStringParameters = event['queryStringParameters']
    pathParameters = event['pathParameters']
    stageVariables = event['stageVariables']

    # Parse the input for the parameter values
    tmp = event['methodArn'].split(':')
    apiGatewayArnTmp = tmp[5].split('/')
    awsAccountId = tmp[4]
    region = tmp[3]
    restApiId = apiGatewayArnTmp[0]
    stage = apiGatewayArnTmp[1]
    method = apiGatewayArnTmp[2]
    resource = '/'

    if (apiGatewayArnTmp[3]):
        resource += apiGatewayArnTmp[3]

    # Perform authorization to return the Allow policy for correct parameters
    # and the 'Unauthorized' error, otherwise.

    if (headers['HeaderAuth1'] == "headerValue1" and queryStringParameters['QueryString1'] == "queryValue1" and stageVariables['StageVar1'] == "stageValue1"):
        response = generateAllow('me', event['methodArn'])
        print('authorized')
        return response
    else:
        print('unauthorized')
        response = generateDeny('me', event['methodArn'])
        return response
    # Help function to generate IAM policy


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17'
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument

    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }

    return authResponse


def generateAllow(principalId, resource):
    return generatePolicy(principalId, 'Allow', resource)


def generateDeny(principalId, resource):
    return generatePolicy(principalId, 'Deny', resource)
```

------

In this example, the Lambda authorizer function checks the input parameters and acts as follows:
+ If all the required parameter values match the expected values, the authorizer function returns a `200 OK` HTTP response and an IAM policy that looks like the following, and the method request succeeds:

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws-cn:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
+ Otherwise, the authorizer function returns a `401 Unauthorized` HTTP response, and the method request fails.

In addition to returning an IAM policy, the Lambda authorizer function must also return the caller's principal identifier. Optionally, it can return a `context` object containing additional information that can be passed into the integration backend. For more information, see [Output from an API Gateway Lambda authorizer](api-gateway-lambda-authorizer-output.md).

In production code, you might need to authenticate the user before granting authorization. You can add authentication logic in the Lambda function by calling an authentication provider as directed in the documentation for that provider.

## Example `TOKEN` authorizer Lambda function


The following example code creates a `TOKEN` Lambda authorizer function that allows a caller to invoke a method if the client-supplied token value is `allow`. The caller is not allowed to invoke the request if the token value is `deny`. If the token value is `unauthorized` or an empty string, the authorizer function returns an `401 UNAUTHORIZED` response.

------
#### [ Node.js ]

```
// A simple token-based authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
// string, the authorizer function returns an HTTP 401 status code. For any other token value, 
// the authorizer returns an HTTP 500 status code. 
// Note that token values are case-sensitive.

export const handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); // Return a 500 Invalid token response
    }
};

// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    var authResponse = {};
    
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; 
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; 
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
```

------
#### [ Python ]

```
# A simple token-based authorizer example to demonstrate how to use an authorization token
# to allow or deny a request. In this example, the caller named 'user' is allowed to invoke
# a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke
# the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
# string, the authorizer function returns an HTTP 401 status code. For any other token value,
# the authorizer returns an HTTP 500 status code.
# Note that token values are case-sensitive.

import json


def lambda_handler(event, context):
    token = event['authorizationToken']
    if token == 'allow':
        print('authorized')
        response = generatePolicy('user', 'Allow', event['methodArn'])
    elif token == 'deny':
        print('unauthorized')
        response = generatePolicy('user', 'Deny', event['methodArn'])
    elif token == 'unauthorized':
        print('unauthorized')
        raise Exception('Unauthorized')  # Return a 401 Unauthorized response
        return 'unauthorized'
    try:
        return json.loads(response)
    except BaseException:
        print('unauthorized')
        return 'unauthorized'  # Return a 500 error


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17'
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument
    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }
    authResponse_JSON = json.dumps(authResponse)
    return authResponse_JSON
```

------

In this example, when the API receives a method request, API Gateway passes the source token to this Lambda authorizer function in the `event.authorizationToken` attribute. The Lambda authorizer function reads the token and acts as follows:
+ If the token value is `allow`, the authorizer function returns a `200 OK` HTTP response and an IAM policy that looks like the following, and the method request succeeds:

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws-cn:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
+ If the token value is `deny`, the authorizer function returns a `200 OK` HTTP response and a `Deny` IAM policy that looks like the following, and the method request fails:

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws-cn:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
**Note**  
Outside of the test environment, API Gateway returns a `403 Forbidden` HTTP response and the method request fails.
+ If the token value is `unauthorized` or an empty string, the authorizer function returns a `401 Unauthorized` HTTP response, and the method call fails.
+ If the token is anything else, the client receives a `500 Invalid token` response, and the method call fails.

In addition to returning an IAM policy, the Lambda authorizer function must also return the caller's principal identifier. Optionally, it can return a `context` object containing additional information that can be passed into the integration backend. For more information, see [Output from an API Gateway Lambda authorizer](api-gateway-lambda-authorizer-output.md).

In production code, you might need to authenticate the user before granting authorization. You can add authentication logic in the Lambda function by calling an authentication provider as directed in the documentation for that provider.

## Additional examples of Lambda authorizer functions
Additional examples of Lambda authorizer functions

The following list shows additional examples of Lambda authorizer functions. You can create a Lambda function in the same account, or a different account, from where you created your API.

For the previous example Lambda functions, you can use the built-in [AWSLambdaBasicExecutionRole](https://docs.amazonaws.cn/lambda/latest/dg/lambda-intro-execution-role.html), as these functions don't call other Amazon services. If your Lambda function calls other Amazon services, you'll need to assign an IAM execution role to the Lambda function. To create the role, follow the instructions in [Amazon Lambda Execution Role](https://docs.amazonaws.cn/lambda/latest/dg/lambda-intro-execution-role.html).

**Additional examples of Lambda authorizer functions**
+  For an example application, see [Open Banking Brazil - Authorization Samples](https://github.com/aws-samples/openbanking-brazilian-auth-samples) on GitHub. 
+  For more example Lambda functions, see [ aws-apigateway-lambda-authorizer-blueprints](https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints) on GitHub. 
+ You can create a Lambda authorizer that authenticates users using Amazon Cognito user pools and authorizes callers based on a policy store using Verified Permissions. For more information, see [Control access based on an identity’s attributes with Verified Permissions](apigateway-lambda-authorizer-verified-permissions.md).
+ The Lambda console provides a Python blueprint, which you can use by choosing **Use a blueprint** and choosing the **api-gateway-authorizer-python** blueprint.

# Configure an API Gateway Lambda authorizer
Configure a Lambda authorizer

After you create a Lambda function, you configure the Lambda function as an authorizer for your API. You then configure your method to invoke your Lambda authorizer to determine if a caller can invoke your method. You can create a Lambda function in the same account, or a different account, from where you created your API.

You can test your Lambda authorizer using built-in tools in the API Gateway console or by using [Postman](https://www.postman.com/). For instructions for how to use Postman to test your Lambda authorizer function, see [Call an API with an API Gateway Lambda authorizer](call-api-with-api-gateway-lambda-authorization.md).

## Configure a Lambda authorizer (console)


 The following procedure shows how to create a Lambda authorizer in the API Gateway REST API console. To learn more about the different types of Lambda authorizers, see [Choosing a type of Lambda authorizer](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-choose). 

------
#### [ REQUEST authorizer ]

**To configure a `REQUEST` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Select an API, and then choose **Authorizers**. 

1. Choose **Create authorizer**. 

1. For **Authorizer name**, enter a name for the authorizer.

1. For **Authorizer type**, select **Lambda**. 

1. For **Lambda function**, select the Amazon Web Services Region where you created your Lambda authorizer function, and then enter the function name.

1. Keep **Lambda invoke role** blank to let the API Gateway REST API console set a resource-based policy. The policy grants API Gateway permissions to invoke the Lambda authorizer function. You can also choose to enter the name of an IAM role to allow API Gateway to invoke the Lambda authorizer function. For an example role, see [Create an assumable IAM role](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies). 

1. For **Lambda event payload**, select **Request**.

1. For **Identity source type**, select a parameter type. Supported parameter types are `Header`, `Query string`, `Stage variable`, and `Context`. To add more identity sources, choose **Add parameter**. 

1. To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, you can modify the **TTL** value. Setting the **TTL** to zero disables policy caching.

   If you enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce a method-specific policy, use the context variables `$context.path` and `$context.httpMethod`.

1. Choose **Create authorizer**.

------
#### [ TOKEN authorizer ]

**To configure a `TOKEN` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Select an API, and then choose **Authorizers**. 

1. Choose **Create authorizer**. 

1. For **Authorizer name**, enter a name for the authorizer.

1. For **Authorizer type**, select **Lambda**. 

1. For **Lambda function**, select the Amazon Web Services Region where you created your Lambda authorizer function, and then enter the function name.

1. Keep **Lambda invoke role** blank to let the API Gateway REST API console set a resource-based policy. The policy grants API Gateway permissions to invoke the Lambda authorizer function. You can also choose to enter the name of an IAM role to allow API Gateway to invoke the Lambda authorizer function. For an example role, see [Create an assumable IAM role](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies). 

1. For **Lambda event payload**, select **Token**.

1. For **Token source**, enter the header name that contains the authorization token. The caller must include a header of this name to send the authorization token to the Lambda authorizer.

1. (Optional) For **Token validation**, enter a RegEx statement. API Gateway performs initial validation of the input token against this expression and invokes the authorizer upon successful validation.

1. To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, the header name specified in **Token source** becomes the cache key. When policy caching is enabled, you can modify the **TTL** value. Setting the **TTL** to zero disables policy caching. 

   If you enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce a method-specific policy, you can turn off **Authorization caching**.

1. Choose **Create authorizer**.

------

After your create your Lambda authorizer, you can test it. The following procedure shows how to test your Lambda authorizer.

------
#### [ REQUEST authorizer ]

**To test a `REQUEST` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Select the name of your authorizer.

1. Under **Test authorizer**, enter a value for your identity source.

   If you are using the [Example `REQUEST` authorizer Lambda function](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-request-lambda-function-create), do the following:

   1. Select **Header** and enter **headerValue1**, and then choose **Add parameter**.

   1. Under **Identity source type**, select **Query string** and enter **queryValue1**, and then choose **Add parameter**.

   1. Under **Identity source type**, select **Stage variable** and enter **stageValue1**.

   You can't modify the context variables for the test invocation, but you can modify the **API Gateway Authorizer** test event template for your Lambda function. Then, you can test your Lambda authorizer function with modified context variables. For more information, see [Testing Lambda functions in the console](https://docs.amazonaws.cn/lambda/latest/dg/testing-functions.html) in the *Amazon Lambda Developer Guide*.

1. Choose **Test authorizer**.

------
#### [ TOKEN authorizer ]

**To test a `TOKEN` Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Select the name of your authorizer.

1. Under **Test authorizer**, enter a value for your token.

   If you are using the [Example `TOKEN` authorizer Lambda function](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-token-lambda-function-create), do the following:

   1. For the **authorizationToken**, enter **allow**.

1. Choose **Test authorizer**.

    If your Lambda authorizer successfully denies a request in the test environment, the test responds with a `200 OK` HTTP response. However, outside of the test environment, API Gateway returns a `403 Forbidden` HTTP response and the method request fails.

------

## Configure a Lambda authorizer (Amazon CLI)


The following [create-authorizer](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-authorizer.html) command shows to create a Lambda authorizer using the Amazon CLI.

------
#### [ REQUEST authorizer ]

The following [create-authorizer](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-authorizer.html) command creates a `REQUEST` authorizer and uses the `Authorizer` header and `accountId` context variable as identity sources:

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Request_Custom_Authorizer' \
    --type REQUEST \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization,context.accountId' \
    --authorizer-result-ttl-in-seconds 300
```

------
#### [ TOKEN authorizer ]

The following [create-authorizer](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-authorizer.html) command creates a `TOKEN` authorizer and uses the `Authorization` header as the identity source:

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Token_Custom_Authorizer' \
    --type TOKEN \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization' \
    --authorizer-result-ttl-in-seconds 300
```

------

After your create your Lambda authorizer, you can test it. The following [test-invoke-authorizer](https://docs.amazonaws.cn/cli/latest/reference/apigateway/test-invoke-authorizer.html) command tests a Lambda authorizer:

```
aws apigateway test-invoke-authorizer --rest-api-id 1234123412 \
   --authorizer-id efg1234 \
   --headers Authorization='Value'
```

## Configure a method to use a Lambda authorizer (console)


After you configure your Lambda authorizer, you must attach it to a method for your API. If your authorizer uses authorization caching, make sure you update the policy to control access for the additional method.

**To configure an API method to use a Lambda authorizer**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Select an API.

1. Choose **Resources**, and then choose a new method or choose an existing method.

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

1. For **Authorizer**, from the dropdown menu, select the Lambda authorizer you just created. 

1.  (Optional) If you want to pass the authorization token to the backend, choose **HTTP request headers**. Choose **Add header**, and then add the name of the authorization header. For **Name**, enter the header name that matches the **Token source** name you specified when you created the Lambda authorizer for the API. This step does not apply to `REQUEST` authorizers. 

1. Choose **Save**.

1. Choose **Deploy API** to deploy the API to a stage. For a `REQUEST` authorizer using stage variables, you must also define the required stage variables and specify their values while on the **Stages ** page.

## Configure a method to use a Lambda authorizer (Amazon CLI)


After you configure your Lambda authorizer, you must attach it to a method for your API. You can create a new method or use a patch operation to attach an authorizer to an existing method. If your authorizer uses authorization caching, make sure you update the policy to control access for the additional method.

The following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command creates a new method that uses an Lambda authorizer:

```
aws apigateway put-method --rest-api-id 1234123412 \
  --resource-id a1b2c3 \
  --http-method PUT \
  --authorization-type CUSTOM \
  --authorizer-id efg1234
```

The following [update-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-method.html) command update an existing method to use a Lambda authorizer:

```
aws apigateway update-method \
    --rest-api-id 1234123412 \
    --resource-id a1b2c3 \
    --http-method PUT \
    --patch-operations op="replace",path="/authorizationType",value="CUSTOM" op="replace",path="/authorizerId",value="efg1234"
```

# Input to an API Gateway Lambda authorizer
Input to a Lambda authorizer

The following section explains the format of the input from API Gateway to a Lambda authorizer.

## `TOKEN` input format


 For a Lambda authorizer (formerly known as a custom authorizer) of the `TOKEN` type, you must specify a custom header as the **Token Source** when you configure the authorizer for your API. The API client must pass the required authorization token in that header in the incoming request. Upon receiving the incoming method request, API Gateway extracts the token from the custom header. It then passes the token as the `authorizationToken` property of the `event` object of the Lambda function, in addition to the method ARN as the `methodArn` property: 

```
{
    "type":"TOKEN",
    "authorizationToken":"{caller-supplied-token}",
    "methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}
```

 In this example, the `type` property specifies the authorizer type, which is a `TOKEN` authorizer. The `{caller-supplied-token}` originates from the authorization header in a client request, and can be any string value. The `methodArn` is the ARN of the incoming method request and is populated by API Gateway in accordance with the Lambda authorizer configuration. 

## `REQUEST` input format


For a Lambda authorizer of the `REQUEST` type, API Gateway passes request parameters to the authorizer Lambda function as part of the `event` object. The request parameters include headers, path parameters, query string parameters, stage variables, and some of request context variables. The API caller can set the path parameters, headers, and query string parameters. The API developer must set the stage variables during the API deployment and API Gateway provides the request context at run time. 

**Note**  
Path parameters can be passed as request parameters to the Lambda authorizer function, but they cannot be used as identity sources.

 The following example shows an input to a `REQUEST` authorizer for an API method (`GET /request`) with a proxy integration: 

```
{
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "resource": "/request",
  "path": "/request",
  "httpMethod": "GET",
  "headers": {
    "X-AMZ-Date": "20170718T062915Z",
    "Accept": "*/*",
    "HeaderAuth1": "headerValue1",
    "CloudFront-Viewer-Country": "US",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "User-Agent": "..."
  },
  "queryStringParameters": {
    "QueryString1": "queryValue1"
  },
  "pathParameters": {},
  "stageVariables": {
    "StageVar1": "stageValue1"
  },
  "requestContext": {
    "path": "/request",
    "accountId": "123456789012",
    "resourceId": "05c7jb",
    "stage": "test",
    "requestId": "...",
    "identity": {
      "apiKey": "...",
      "sourceIp": "...",
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "resourcePath": "/request",
    "httpMethod": "GET",
    "apiId": "abcdef123"
  }
}
```

 The `requestContext` is a map of key-value pairs and corresponds to the [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) variable. Its outcome is API-dependent.

 API Gateway might add new keys to the map. For more information about Lambda function input in Lambda proxy integration, see [Input format of a Lambda function for proxy integration](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format). 

# Output from an API Gateway Lambda authorizer


A Lambda authorizer function's output is a dictionary-like object, which must include the principal identifier (`principalId`) and a policy document (`policyDocument`) containing a list of policy statements. The output can also include a `context` map containing key-value pairs. If the API uses a usage plan (the [https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html#apiKeySource](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html#apiKeySource) is set to `AUTHORIZER`), the Lambda authorizer function must return one of the usage plan's API keys as the `usageIdentifierKey` property value.

The following shows an example of this output. 

------
#### [ JSON ]

****  

```
{
  "principalId": "yyyyyyyy", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws-cn:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "stringKey": "value",
    "numberKey": "1",
    "booleanKey": "true"
  },
  "usageIdentifierKey": "{api-key}"
}
```

------

 Here, a policy statement specifies whether to allow or deny (`Effect`) the API Gateway execution service to invoke (`Action`) the specified API method (`Resource`). You might need to control access to multiple resources based on your authorizer. You can use a wild card (`*`) to specify a resource type (method). For information about setting valid policies for calling an API, see [Statement reference of IAM policies for executing API in API Gateway](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-calling-api-permissions). 

For an authorization-enabled method ARN, e.g., `arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]`, the maximum length is 1600 bytes. The path parameter values, the size of which are determined at run time, can cause the ARN length to exceed the limit. When this happens, the API client will receive a `414 Request URI too long` response. 

In addition, the Resource ARN, as shown in the policy statement output by the authorizer, is currently limited to 512 characters long. For this reason, you must not use URI with a JWT token of a significant length in a request URI. You can safely pass the JWT token in a request header, instead.

 You can access the `principalId` value in a mapping template using the `$context.authorizer.principalId` variable. This is useful if you want to pass the value to the backend. For more information, see [Context variables for data transformations](api-gateway-mapping-template-reference.md#context-variable-reference). 

 You can access the `stringKey`, `numberKey`, or `booleanKey` value (for example, `"value"`, `"1"`, or `"true"`) of the `context` map in a mapping template by calling `$context.authorizer.stringKey`, `$context.authorizer.numberKey`, or `$context.authorizer.booleanKey`, respectively. The returned values are all stringified. Notice that you cannot set a JSON object or array as a valid value of any key in the `context` map. 

 You can use the `context` map to return cached credentials from the authorizer to the backend, using an integration request mapping template. This enables the backend to provide an improved user experience by using the cached credentials to reduce the need to access the secret keys and open the authorization tokens for every request. 

 For the Lambda proxy integration, API Gateway passes the `context` object from a Lambda authorizer directly to the backend Lambda function as part of the input `event`. You can retrieve the `context` key-value pairs in the Lambda function by calling `$event.requestContext.authorizer.key`. 

`{api-key}` stands for an API key in the API stage's usage plan. For more information, see [Usage plans and API keys for REST APIs in API Gateway](api-gateway-api-usage-plans.md).

 The following shows example output from the example Lambda authorizer. The example output contains a policy statement to block (`Deny`) calls to the `GET` method for the `dev` stage of an API (`ymy8tbxw7b`) of an Amazon account (`123456789012`).

------
#### [ JSON ]

****  

```
{
  "principalId": "user",
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws-cn:execute-api:us-west-2:123456789012:ymy8tbxw7b/dev/GET/"
      }
    ]
  }
}
```

------

# Call an API with an API Gateway Lambda authorizer
Call an API with Lambda authorizers

 Having configured the Lambda authorizer (formerly known as the custom authorizer) and deployed the API, you should test the API with the Lambda authorizer enabled. For this, you need a REST client, such as cURL or [Postman](https://www.postman.com/). For the following examples, we use Postman. 

**Note**  
 When calling an authorizer-enabled method, API Gateway does not log the call to CloudWatch if the required token for the `TOKEN` authorizer is not set, is null, or is invalidated by the specified **Token validation expression**. Similarly, API Gateway does not log the call to CloudWatch if any of the required identity sources for the `REQUEST` authorizer are not set, are null, or are empty.

 In the following, we show how to use Postman to call or test an API with a Lambda `TOKEN` authorizer. The method can be applied to calling an API with a Lambda `REQUEST` authorizer, if you specify the required path, header, or query string parameters explicitly. 

**To call an API with the custom `TOKEN` authorizer**

1.  Open **Postman**, choose the **GET** method, and paste the API's **Invoke URL** into the adjacent URL field. 

    Add the Lambda authorization token header and set the value to `allow`. Choose **Send**. 

    The response shows that the API Gateway Lambda authorizer returns a **200 OK** response and successfully authorizes the call to access the HTTP endpoint (http://httpbin.org/get) integrated with the method. 

1.  Still in Postman, change the Lambda authorization token header value to `deny`. Choose **Send**. 

   The response shows that the API Gateway Lambda authorizer returns a **403 Forbidden** response without authorizing the call to access the HTTP endpoint.

1.  In Postman, change the Lambda authorization token header value to `unauthorized` and choose **Send**. 

    The response shows that API Gateway returns a **401 Unauthorized** response without authorizing the call to access the HTTP endpoint. 

1.  Now, change the Lambda authorization token header value to `fail`. Choose **Send**. 

    The response shows that API Gateway returns a **500 Internal Server Error** response without authorizing the call to access the HTTP endpoint. 

# Configure a cross-account API Gateway Lambda authorizer
Configure a cross-account Lambda authorizer

You can now also use an Amazon Lambda function from a different Amazon account as your API authorizer function. Each account can be in any region where Amazon API Gateway is available. The Lambda authorizer function can use bearer token authentication strategies such as OAuth or SAML. This makes it easy to centrally manage and share a central Lambda authorizer function across multiple API Gateway APIs.

In this section, we show how to configure a cross-account Lambda authorizer function using the Amazon API Gateway console.

These instructions assume that you already have an API Gateway API in one Amazon account and a Lambda authorizer function in another account.

## Configure a cross-account Lambda authorizer using the API Gateway console


Log in to the Amazon API Gateway console in the account that has your API in it, and then do the following:

1. Choose your API, and then in the main navigation pane, choose **Authorizers**.

1. Choose **Create authorizer**. 

1. For **Authorizer name**, enter a name for the authorizer.

1. For **Authorizer type**, select **Lambda**.

1. For **Lambda Function**, enter the full ARN for the Lambda authorizer function that you have in your second account.
**Note**  
In the Lambda console, you can find the ARN for your function in the upper right corner of the console window.

1. A warning with an `aws lambda add-permission` command string will appear. This policy grants API Gateway permission to invoke the authorizer Lambda function. Copy the command and save it for later. You run the command after you create the authorizer.

1. For **Lambda event payload**, select either **Token** for a `TOKEN` authorizer or **Request** for a `REQUEST` authorizer.

1. Depending on the choice of the previous step, do one of the following:

   1.  For the **Token** option, do the following: 
      + For **Token source**, enter the header name that contains the authorization token. The API client must include a header of this name to send the authorization token to the Lambda authorizer. 
      + Optionally, for **Token validation**, enter a RegEx statement. API Gateway performs initial validation of the input token against this expression and invokes the authorizer upon successful validation. This helps reduce calls to your API. 
      + To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, you can choose to modify the **TTL** value. Setting the **TTL** to zero disables policy caching. When policy caching is enabled, the header name specified in **Token source** becomes the cache key. If multiple values are passed to this header in the request, all values will become the cache key, with the order preserved.
**Note**  
The default **TTL** value is 300 seconds. The maximum value is 3600 seconds; this limit cannot be increased.

   1. For the **Request** option, do the following:
      + For **Identity source type**, select a parameter type. Supported parameter types are `Header`, `Query string`, `Stage variable`, and `Context`. To add more identity sources, choose **Add parameter**. 
      + To cache the authorization policy generated by the authorizer, keep **Authorization caching** turned on. When policy caching is enabled, you can choose to modify the **TTL** value. Setting the **TTL** to zero disables policy caching.

        API Gateway uses the specified identity sources as the request authorizer caching key. When caching is enabled, API Gateway calls the authorizer's Lambda function only after successfully verifying that all the specified identity sources are present at runtime. If a specified identity source is missing, null, or empty, API Gateway returns a `401 Unauthorized` response without calling the authorizer Lambda function. 

        When multiple identity sources are defined, they are all used to derive the authorizer's cache key. Changing any of the cache key parts causes the authorizer to discard the cached policy document and generate a new one. If a header with multiple values is passed in the request, then all values will be part of the cache key, with the order preserved. 
      + When caching is turned off, it is not necessary to specify an identity source.
**Note**  
 To enable caching, your authorizer must return a policy that is applicable to all methods across an API. To enforce method-specific policy, you can turn off **Authorization caching**. 

1. Choose **Create authorizer**.

1. Paste the `aws lambda add-permission` command string that you copied in a previous step into an Amazon CLI window that is configured for your second account. Replace `AUTHORIZER_ID` with your authorizer's ID. This will grant your first account access to your second account's Lambda authorizer function.

# Control access based on an identity’s attributes with Verified Permissions


Use Amazon Verified Permissions to control access to your API Gateway API. When you use API Gateway with Verified Permissions, Verified Permissions creates a Lambda authorizer that uses fine-grained authorization decisions to control access to your API. Verified Permissions authorizes callers based on a policy store schema and policies using the Cedar policy language to define fine-grained permissions for application users. For more information, see [Create a policy store with a connected API and identity provider](https://docs.amazonaws.cn/verifiedpermissions/latest/userguide/getting-started-api-policy-store.html) in the *Amazon Verified Permissions User Guide*.

Verified Permissions supports Amazon Cognito user pools or OpenID Connect (OIDC) identity providers as identity sources. Verified Permissions presumes that the principal has been previously identified and authenticated. Verified Permissions is only supported for Regional and edge-optimized REST APIs.

## Create a Lambda authorizer using Verified Permissions


Verified Permissions creates a Lambda authorizer to determine if a principal is allowed to perform an action on your API. You create the Cedar policy that Verified Permissions uses to perform its authorization tasks.

The following is an example Cedar policy that allows access to invoke an API based on the Amazon Cognito user pool, `us-east-1_ABC1234` for the `developer` group on the `GET /users` resource of an API. Verified Permissions determines group membership by parsing the bearer token for the caller's identity. 

```
permit(
  principal in MyAPI::UserGroup::"us-east-1_ABC1234|developer",
  action in [ MyAPI::Action::"get /users" ],
  resource
  );
```

Optionally, Verified Permissions can attach the authorizer to the methods of your API. On production stages for your API, we recommend that you don't allow Verified Permissions to attach the authorizer for you.

The following list show how to configure Verified Permissions to attach or not to attach the Lambda authorizer to the method request of your API's methods.

**Attach the authorizer for you (Amazon Web Services Management Console)**  
When you choose **Create policy store** in the Verified Permissions console, on the **Deploy app integration** page, choose **Now**.

**Don't attach the authorizer for you (Amazon Web Services Management Console)**  
When you choose **Create policy store** in the Verified Permissions console, on the **Deploy app integration** page, choose **Later**.  
Verified Permissions still creates a Lambda authorizer for you. The Lambda authorizer starts with `AVPAuthorizerLambda-`. For more instructions on how to attach your authorizer on a method, see [Configure a method to use a Lambda authorizer (console)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-console).

**Attach the authorizer for you (Amazon CloudFormation)**  
In the Verified Permissions-generated Amazon CloudFormation template, in the `Conditions` section, set `"Ref": "shouldAttachAuthorizer"` to `true`.

**Don't attach the authorizer for you (Amazon CloudFormation)**  
In the Verified Permissions-generated Amazon CloudFormation template, in the `Conditions` section, set `"Ref": "shouldAttachAuthorizer"` to `false`.  
Verified Permissions still creates a Lambda authorizer for you. The Lambda authorizer starts with `AVPAuthorizerLambda-`. For more instructions on how to attach your authorizer on a method, see [Configure a method to use a Lambda authorizer (Amazon CLI)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-cli).

## Call a Lambda authorizer using Verified Permissions


You can call your Lambda authorizer by providing an identity or access token in the `Authorization` header. For more information, see [Call an API with an API Gateway Lambda authorizer](call-api-with-api-gateway-lambda-authorization.md).

API Gateway caches the policy that your Lambda authorizer returns for 120 seconds. You can modify the TTL in the API Gateway console or by using the Amazon CLI.

# Control access to REST APIs using Amazon Cognito user pools as an authorizer
Use Amazon Cognito user pool as authorizer for a REST API

As an alternative to using [IAM roles and policies](permissions.md) or [Lambda authorizers](apigateway-use-lambda-authorizer.md) (formerly known as custom authorizers), you can use an [Amazon Cognito user pool](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-user-identity-pools.html) to control who can access your API in Amazon API Gateway. 

To use an Amazon Cognito user pool with your API, you must first create an authorizer of the `COGNITO_USER_POOLS` type and then configure an API method to use that authorizer. After the API is deployed, the client must first sign the user in to the user pool, obtain an [identity or access token](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html) for the user, and then call the API method with one of the tokens, which are typically set to the request's `Authorization` header. The API call succeeds only if the required token is supplied and the supplied token is valid, otherwise, the client isn't authorized to make the call because the client did not have credentials that could be authorized. 

The identity token is used to authorize API calls based on identity claims of the signed-in user. The access token is used to authorize API calls based on the custom scopes of specified access-protected resources. For more information, see [Using Tokens with User Pools](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html) and [Resource Server and Custom Scopes](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html).

To create and configure an Amazon Cognito user pool for your API, you perform the following tasks:
+ Use the Amazon Cognito console, CLI/SDK, or API to create a user pool—or use one that's owned by another Amazon account.
+ Use the API Gateway console, CLI/SDK, or API to create an API Gateway authorizer with the chosen user pool.
+ Use the API Gateway console, CLI/SDK, or API to enable the authorizer on selected API methods.

 To call any API methods with a user pool enabled, your API clients perform the following tasks:
+  Use the Amazon Cognito CLI/SDK or API to sign a user in to the chosen user pool, and obtain an identity token or access token. To learn more about using the SDKs, see [Code examples for Amazon Cognito using Amazon SDKs](https://docs.amazonaws.cn/cognito/latest/developerguide/service_code_examples.html).
+  Use a client-specific framework to call the deployed API Gateway API and supply the appropriate token in the `Authorization` header.

As the API developer, you must provide your client developers with the user pool ID, a client ID, and possibly the associated client secrets that are defined as part of the user pool. 

**Note**  
To let a user sign in using Amazon Cognito credentials and also obtain temporary credentials to use with the permissions of an IAM role, use [Amazon Cognito Federated Identities](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-identity.html). For each API resource endpoint HTTP method, set the authorization type, category `Method Execution`, to `AWS_IAM`. 

In this section, we describe how to create a user pool, how to integrate an API Gateway API with the user pool, and how to invoke an API that's integrated with the user pool. 

**Topics**
+ [

# Create an Amazon Cognito user pool for a REST API
](apigateway-create-cognito-user-pool.md)
+ [

# Integrate a REST API with an Amazon Cognito user pool
](apigateway-enable-cognito-user-pool.md)
+ [

# Call a REST API integrated with an Amazon Cognito user pool
](apigateway-invoke-api-integrated-with-cognito-user-pool.md)
+ [

# Configure cross-account Amazon Cognito authorizer for a REST API using the API Gateway console
](apigateway-cross-account-cognito-authorizer.md)
+ [

# Create an Amazon Cognito authorizer for a REST API using Amazon CloudFormation
](apigateway-cognito-authorizer-cfn.md)

# Create an Amazon Cognito user pool for a REST API


Before integrating your API with a user pool, you must create the user pool in Amazon Cognito. Your user pool configuration must follow all [resource quotas for Amazon Cognito](https://docs.amazonaws.cn/cognito/latest/developerguide/limits.html). All user-defined Amazon Cognito variables such as groups, users, and roles should use only alphanumeric characters. For instructions on how to create a user pool, see [Tutorial: Creating a user pool](https://docs.amazonaws.cn/cognito/latest/developerguide/tutorial-create-user-pool.html) in the *Amazon Cognito Developer Guide*.

Note the user pool ID, client ID, and any client secret. The client must provide them to Amazon Cognito for the user to register with the user pool, to sign in to the user pool, and to obtain an identity or access token to be included in requests to call API methods that are configured with the user pool. Also, you must specify the user pool name when you configure the user pool as an authorizer in API Gateway, as described next.

If you're using access tokens to authorize API method calls, be sure to configure the app integration with the user pool to set up the custom scopes that you want on a given resource server. For more information about using tokens with Amazon Cognito user pools, see [Using Tokens with User Pools](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html). For more information about resource servers, see [Defining Resource Servers for Your User Pool](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html).

Note the configured resource server identifiers and custom scope names. You need them to construct the access scope full names for **OAuth Scopes**, which is used by the `COGNITO_USER_POOLS` authorizer. 

# Integrate a REST API with an Amazon Cognito user pool


After creating an Amazon Cognito user pool, in API Gateway, you must then create a `COGNITO_USER_POOLS` authorizer that uses the user pool. The following procedure shows you how to do this using the API Gateway console.

**Note**  
You can use the [https://docs.amazonaws.cn/apigateway/latest/api/API_CreateAuthorizer.html](https://docs.amazonaws.cn/apigateway/latest/api/API_CreateAuthorizer.html) action to create a `COGNITO_USER_POOLS` authorizer that uses multiple user pools. You can use up to 1,000 user pools for one `COGNITO_USER_POOLS` authorizer. This limit cannot be increased.

**Important**  
After performing any of the procedures below, you'll need to deploy or redeploy your API to propagate the changes. For more information about deploying your API, see [Deploy REST APIs in API Gateway](how-to-deploy-api.md).

**To create a `COGNITO_USER_POOLS` authorizer by using the API Gateway console**

1. Create a new API, or select an existing API in API Gateway.

1. In the main navigation pane, choose **Authorizers**.

1. Choose **Create authorizer**. 

1. To configure the new authorizer to use a user pool, do the following:

   1.  For **Authorizer name**, enter a name. 

   1. For **Authorizer type**, select **Cognito**.

   1. For **Cognito user pool**, choose the Amazon Web Services Region where you created your Amazon Cognito and select an available user pool.

      You can use a stage variable to define your user pool. Use the following format for your user pool: `arn:aws-cn:cognito-idp:us-west-2:111122223333:userpool/${stageVariables.MyUserPool}`.

   1.  For **Token source**, enter **Authorization** as the header name to pass the identity or access token that's returned by Amazon Cognito when a user signs in successfully. 

   1. (Optional) Enter a regular expression in the **Token validation** field to validate the `aud` (audience) field of the identity token before the request is authorized with Amazon Cognito. Note that when using an access token this validation rejects the request due to the access token not containing the `aud` field.

   1. Choose **Create authorizer**. 

1. After creating the `COGNITO_USER_POOLS` authorizer, you can test invoke it by supplying an identity token that's provisioned from the user pool. You can't use an access token to test invoke your authorizer.

   You can obtain this identity token by calling the [Amazon Cognito Identity SDK](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-integrate-apps.html) to perform user sign-in. You can also use the [https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) action. If you do not configure any **Authorization scopes**, API Gateway treats the supplied token as an identity token. 

The preceding procedure creates a `COGNITO_USER_POOLS` authorizer that uses the newly created Amazon Cognito user pool. Depending on how you enable the authorizer on an API method, you can use either an identity token or an access token that's provisioned from the integrated user pool.

**To configure a `COGNITO_USER_POOLS` authorizer on methods**

1. Choose **Resources**. Choose a new method or choose an existing method. If necessary, create a resource.

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

1. For **Authorizer**, from the dropdown menu, select the **Amazon Cognito user pool authorizers** you just created.

1.  To use an identity token, do the following:

   1. Keep **Authorization Scopes** empty.

   1. If needed, in the **Integration request**, add the `$context.authorizer.claims['property-name']` or `$context.authorizer.claims.property-name` expressions in a body-mapping template to pass the specified identity claims property from the user pool to the backend. For simple property names, such as `sub` or `custom-sub`, the two notations are identical. For complex property names, such as `custom:role`, you can't use the dot notation. For example, the following mapping expressions pass the claim's [standard fields](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) of `sub` and `email` to the backend:

      ```
      {
      	"context" : {
      		"sub" : "$context.authorizer.claims.sub",
      		"email" : "$context.authorizer.claims.email"
      	}
      }
      ```

      If you declared a custom claim field when you configured a user pool, you can follow the same pattern to access the custom fields. The following example gets a custom `role` field of a claim:

      ```
      {
      	"context" : {
      		"role" : "$context.authorizer.claims.role"
          }
      }
      ```

      If the custom claim field is declared as `custom:role`, use the following example to get the claim's property:

      ```
      {
      	"context" : {
      		"role" : "$context.authorizer.claims['custom:role']"
          }
      }
      ```

1.  To use an access token, do the following: 

   1. For **Authorization Scopes**, enter one or more full names of a scope that has been configured when the Amazon Cognito user pool was created. For example, following the example given in [Create an Amazon Cognito user pool for a REST API](apigateway-create-cognito-user-pool.md), one of the scopes is `https://my-petstore-api.example.com/cats.read`. 

      At runtime, the method call succeeds if any scope that's specified on the method in this step matches a scope that's claimed in the incoming token. Otherwise, the call fails with a `401 Unauthorized` response.

   1.  Choose **Save**.

1. Repeat these steps for other methods that you choose.

With the `COGNITO_USER_POOLS` authorizer, if the **OAuth Scopes** option isn't specified, API Gateway treats the supplied token as an identity token and verifies the claimed identity against the one from the user pool. Otherwise, API Gateway treats the supplied token as an access token and verifies the access scopes that are claimed in the token against the authorization scopes declared on the method.

Instead of using the API Gateway console, you can also enable an Amazon Cognito user pool on a method by specifying an OpenAPI definition file and importing the API definition into API Gateway.

**To import a COGNITO\$1USER\$1POOLS authorizer with an OpenAPI definition file**

1. Create (or export) an OpenAPI definition file for your API.

1. Specify the `COGNITO_USER_POOLS` authorizer (`MyUserPool`) JSON definition as part of the `securitySchemes` section in OpenAPI 3.0 or the `securityDefinitions` section in Open API 2.0 as follows:

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

   ```
     "securitySchemes": {
       "MyUserPool": {
         "type": "apiKey",
         "name": "Authorization",
         "in": "header",
         "x-amazon-apigateway-authtype": "cognito_user_pools",
         "x-amazon-apigateway-authorizer": {
           "type": "cognito_user_pools",
           "providerARNs": [
             "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
           ]
         }
       }
   ```

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

   ```
     "securityDefinitions": {
       "MyUserPool": {
         "type": "apiKey",
         "name": "Authorization",
         "in": "header",
         "x-amazon-apigateway-authtype": "cognito_user_pools",
         "x-amazon-apigateway-authorizer": {
           "type": "cognito_user_pools",
           "providerARNs": [
             "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
           ]
         }
       }
   ```

------

1. To use the identity token for method authorization, add `{ "MyUserPool": [] }` to the `security` definition of the method, as shown in the following GET method on the root resource.

   ```
     "paths": {
       "/": {
         "get": {
           "consumes": [
             "application/json"
           ],
           "produces": [
             "text/html"
           ],
           "responses": {
             "200": {
               "description": "200 response",
               "headers": {
                 "Content-Type": {
                   "type": "string"
                 }
               }
             }
           },
           "security": [
             {
               "MyUserPool": []
             }
           ],        
           "x-amazon-apigateway-integration": {
             "type": "mock",
             "responses": {
               "default": {
                 "statusCode": "200",
                 "responseParameters": {
                   "method.response.header.Content-Type": "'text/html'"
                 },
               }
             },
             "requestTemplates": {
               "application/json": "{\"statusCode\": 200}"
             },
             "passthroughBehavior": "when_no_match"
           }
         },
         ...
      }
   ```

1.  To use the access token for method authorization, change the above security definition to `{ "MyUserPool": [resource-server/scope, ...] }`:

   ```
     "paths": {
       "/": {
         "get": {
           "consumes": [
             "application/json"
           ],
           "produces": [
             "text/html"
           ],
           "responses": {
             "200": {
               "description": "200 response",
               "headers": {
                 "Content-Type": {
                   "type": "string"
                 }
               }
             }
           },
           "security": [
             {
               "MyUserPool": ["https://my-petstore-api.example.com/cats.read", "http://my.resource.com/file.read"]
             }
           ],        
           "x-amazon-apigateway-integration": {
             "type": "mock",
             "responses": {
               "default": {
                 "statusCode": "200",
                 "responseParameters": {
                   "method.response.header.Content-Type": "'text/html'"
                 },
               }
             },
             "requestTemplates": {
               "application/json": "{\"statusCode\": 200}"
             },
             "passthroughBehavior": "when_no_match"
           }
         },
         ...
      }
   ```

1. If needed, you can set other API configuration settings by using the appropriate OpenAPI definitions or extensions. For more information, see [OpenAPI extensions for API Gateway](api-gateway-swagger-extensions.md).

# Call a REST API integrated with an Amazon Cognito user pool
Call a REST API integrated with a user pool

To call a method with a user pool authorizer configured, the client must do the following: 
+ Enable the user to sign up with the user pool.
+ Enable the user to sign in to the user pool.
+ Obtain an [identity or access token](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html) of the signed-in user from the user pool.
+ Include the token in the `Authorization` header (or another header you specified when you created the authorizer).

You can use [Amazon Amplify]() to perform these tasks. See [Integrating Amazon Cognito With Web and Mobile Apps](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-integrate-apps.html) for more information.
+ For Android, see [Getting Started with Amplify for Android](https://docs.amplify.aws/android/build-a-backend/auth/).
+ To use iOS see [Getting started with Amplify for iOS](https://docs.amplify.aws/swift/build-a-backend/auth/).
+ To use JavaScript, see [Getting Started with Amplify for Javascript](https://docs.amplify.aws/javascript/build-a-backend/auth/).

# Configure cross-account Amazon Cognito authorizer for a REST API using the API Gateway console
Configure cross-account Amazon Cognito authorizer for a REST API

You can now also use a Amazon Cognito user pool from a different Amazon account as your API authorizer. The Amazon Cognito user pool can use bearer token authentication strategies such as OAuth or SAML. This makes it easy to centrally manage and share a central Amazon Cognito user pool authorizer across multiple API Gateway APIs.

In this section, we show how to configure a cross-account Amazon Cognito user pool using the Amazon API Gateway console.

These instructions assume that you already have an API Gateway API in one Amazon account and a Amazon Cognito user pool in another account.

## Create a cross-account Amazon Cognito authorizer for a REST API


Log in to the Amazon API Gateway console in the account that has your API in it, and then do the following:

1. Create a new API, or select an existing API in API Gateway.

1. In the main navigation pane, choose **Authorizers**.

1. Choose **Create authorizer**.

1. To configure the new authorizer to use a user pool, do the following:

   1.  For **Authorizer name**, enter a name. 

   1. For **Authorizer type**, select **Cognito**.

   1. For **Cognito user pool**, enter the full ARN for the user pool that you have in your second account.
**Note**  
In the Amazon Cognito console, you can find the ARN for your user pool in the **Pool ARN** field of the **General Settings** pane.

   1.  For **Token source**, enter **Authorization** as the header name to pass the identity or access token that's returned by Amazon Cognito when a user signs in successfully. 

   1. (Optional) Enter a regular expression in the **Token validation** field to validate the `aud` (audience) field of the identity token before the request is authorized with Amazon Cognito. Note that when using an access token this validation rejects the request due to the access token not containing the `aud` field.

   1. Choose **Create authorizer**.

# Create an Amazon Cognito authorizer for a REST API using Amazon CloudFormation


You can use Amazon CloudFormation to create an Amazon Cognito user pool and an Amazon Cognito authorizer. The example Amazon CloudFormation template does the following: 
+ Create an Amazon Cognito user pool. The client must first sign the user in to the user pool and obtain an [identity or access token](https://docs.amazonaws.cn/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html). If you're using access tokens to authorize API method calls, be sure to configure the app integration with the user pool to set up the custom scopes that you want on a given resource server.
+ Creates an API Gateway API with a `GET` method.
+ Creates an Amazon Cognito authorizer that uses the `Authorization` header as the token source.

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_phone_number
            Priority: 1
          - Name: verified_email
            Priority: 2
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      EmailVerificationMessage: The verification code to your new account is {####}
      EmailVerificationSubject: Verify your new account
      SmsVerificationMessage: The verification code to your new account is {####}
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
        EmailMessage: The verification code to your new account is {####}
        EmailSubject: Verify your new account
        SmsMessage: The verification code to your new account is {####}
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
  CogAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Name: CognitoAuthorizer
      RestApiId:
        Ref: Api
      Type: COGNITO_USER_POOLS
      IdentitySource: method.request.header.Authorization
      ProviderARNs:
        - Fn::GetAtt:
            - UserPool
            - Arn
  Api:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: MyCogAuthApi
  ApiDeployment:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId:
        Ref: Api
    DependsOn:
      - CogAuthorizer
      - ApiGET
  ApiDeploymentStageprod:
    Type: AWS::ApiGateway::Stage
    Properties:
      RestApiId:
        Ref: Api
      DeploymentId:
        Ref: ApiDeployment
      StageName: prod
  ApiGET:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: GET
      ResourceId:
        Fn::GetAtt:
          - Api
          - RootResourceId
      RestApiId:
        Ref: Api
      AuthorizationType: COGNITO_USER_POOLS
      AuthorizerId:
        Ref: CogAuthorizer
      Integration:
        IntegrationHttpMethod: GET
        Type: HTTP_PROXY
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
Outputs:
  ApiEndpoint:
    Value:
      Fn::Join:
        - ""
        - - https://
          - Ref: Api
          - .execute-api.
          - Ref: AWS::Region
          - "."
          - Ref: AWS::URLSuffix
          - /
          - Ref: ApiDeploymentStageprod
          - /
```

# Integrations for REST APIs in API Gateway
Integrations

 After setting up an API method, you must integrate it with an endpoint in the backend. A backend endpoint is also referred to as an integration endpoint and can be a Lambda function, an HTTP webpage, or an Amazon service action. 

As with the API method, the API integration has an integration request and an integration response. An integration request encapsulates an HTTP request received by the backend. It might or might not differ from the method request submitted by the client. An integration response is an HTTP response encapsulating the output returned by the backend.

Setting up an integration request involves the following: configuring how to pass client-submitted method requests to the backend; configuring how to transform the request data, if necessary, to the integration request data; and specifying which Lambda function to call, specifying which HTTP server to forward the incoming request to, or specifying the Amazon service action to invoke.

Setting up an integration response (applicable to non-proxy integrations only) involves the following: configuring how to pass the backend-returned result to a method response of a given status code, configuring how to transform specified integration response parameters to preconfigured method response parameters, and configuring how to map the integration response body to the method response body according to the specified body-mapping templates. 

Programmatically, an integration request is encapsulated by the [https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource and an integration response by the [https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resource of API Gateway. 

To set up an integration request, you create an [https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource and use it to configure the integration endpoint URL. You then set the IAM permissions to access the backend, and specify mappings to transform the incoming request data before passing it to the backend. To set up an integration response for non-proxy integration, you create an [https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resource and use it to set its target method response. You then configure how to map backend output to the method response.

**Topics**
+ [

# Set up an integration request in API Gateway
](api-gateway-integration-settings-integration-request.md)
+ [

# Set up an integration response in API Gateway
](api-gateway-integration-settings-integration-response.md)
+ [

# Lambda integrations for REST APIs in API Gateway
](set-up-lambda-integrations.md)
+ [

# HTTP integrations for REST APIs in API Gateway
](setup-http-integrations.md)
+ [

# Stream the integration response for your proxy integrations in API Gateway
](response-transfer-mode.md)
+ [

# Private integrations for REST APIs in API Gateway
](private-integration.md)
+ [

# Mock integrations for REST APIs in API Gateway
](how-to-mock-integration.md)

# Set up an integration request in API Gateway
Integration request

To set up an integration request, you perform the following required and optional tasks:

1.  Choose an integration type that determines how method request data is passed to the backend.

1.  For non-mock integrations, specify an HTTP method and the URI of the targeted integration endpoint, except for the `MOCK` integration.

1.  For integrations with Lambda functions and other Amazon service actions, set an IAM role with required permissions for API Gateway to call the backend on your behalf.

1.  For non-proxy integrations, set necessary parameter mappings to map predefined method request parameters to appropriate integration request parameters.

1.  For non-proxy integrations, set necessary body mappings to map the incoming method request body of a given content type according to the specified mapping template.

1.  For non-proxy integrations, specify the condition under which the incoming method request data is passed through to the backend as-is. 

1.  Optionally, specify how to handle type conversion for a binary payload.

1.  Optionally, declare a cache namespace name and cache key parameters to enable API caching. 

 Performing these tasks involves creating an [Integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource of API Gateway and setting appropriate property values. You can do so using the API Gateway console, Amazon CLI commands, an Amazon SDK, or the API Gateway REST API. 

**Topics**
+ [

# Basic tasks of an API integration request
](integration-request-basic-setup.md)
+ [

# Choose an API Gateway API integration type
](api-gateway-api-integration-types.md)
+ [

# Set up a proxy integration with a proxy resource
](api-gateway-set-up-simple-proxy.md)
+ [

# Set up an API integration request using the API Gateway console
](how-to-method-settings-console.md)

# Basic tasks of an API integration request


 An integration request is an HTTP request that API Gateway submits to the backend, passing along the client-submitted request data, and transforming the data, if necessary. The HTTP method (or verb) and URI of the integration request are dictated by the backend (that is, the integration endpoint). They can be the same as or different from the method request's HTTP method and URI, respectively. 

For example, when a Lambda function returns a file that is fetched from Amazon S3, you can expose this operation intuitively as a `GET` method request to the client even though the corresponding integration request requires that a `POST` request be used to invoke the Lambda function. For an HTTP endpoint, it is likely that the method request and the corresponding integration request both use the same HTTP verb. However, this is not required. You can integrate the following method request: 

```
GET /{var}?query=value
Host: api.domain.net
```

With the following integration request: 

```
POST /
Host: service.domain.com
Content-Type: application/json
Content-Length: ...

{
   path: "{var}'s value",
   type: "value"
}
```

 As an API developer, you can use whatever HTTP verb and URI for a method request suit your requirements. But you must follow the requirements of the integration endpoint. When the method request data differs from the integration request data, you can reconcile the difference by providing mappings from the method request data to the integration request data. 

In the preceding examples, the mapping translates the path variable (`{var}`) and the query parameter (`query`) values of the `GET` method request to the values of the integration request's payload properties of `path` and `type`. Other mappable request data includes request headers and body. These are described in [Parameter mapping for REST APIs in API Gateway](rest-api-parameter-mapping.md).

When setting up the HTTP or HTTP proxy integration request, you assign the backend HTTP endpoint URL as the integration request URI value. For example, in the PetStore API, the method request to get a page of pets has the following integration request URI: 

```
http://petstore-demo-endpoint.execute-api.com/petstore/pets
```

When setting up the Lambda or Lambda proxy integration, you assign the Amazon Resource Name (ARN) for invoking the Lambda function as the integration request URI value. This ARN has the following format:

```
arn:aws:apigateway:api-region:lambda:path//2015-03-31/functions/arn:aws:lambda:lambda-region:account-id:function:lambda-function-name/invocations
```

The part after `arn:aws:apigateway:api-region:lambda:path/`, namely, `/2015-03-31/functions/arn:aws:lambda:lambda-region:account-id:function:lambda-function-name/invocations`, is the REST API URI path of the Lambda [Invoke](https://docs.amazonaws.cn/lambda/latest/dg/API_Invoke.html) action. If you use the API Gateway console to set up the Lambda integration, API Gateway creates the ARN and assigns it to the integration URI after prompting you to choose the `lambda-function-name` from a region. 

When setting up the integration request with another Amazon service action, the integration request URI is also an ARN, similar to the integration with the Lambda `Invoke` action. For example, for the integration with the [GetBucket](https://docs.amazonaws.cn/AmazonS3/latest/API/API_ListObjects.html) action of Amazon S3, the integration request URI is an ARN of the following format:

```
arn:aws:apigateway:api-region:s3:path/{bucket}
```

The integration request URI is of the path convention to specify the action, where `{bucket}` is the placeholder of a bucket name. Alternatively, an Amazon service action can be referenced by its name. Using the action name, the integration request URI for the `GetBucket` action of Amazon S3 becomes the following:

```
arn:aws:apigateway:api-region:s3:action/GetBucket
```

With the action-based integration request URI, the bucket name (`{bucket}`) must be specified in the integration request body (`{ Bucket: "{bucket}" }`), following the input format of `GetBucket` action. 

For Amazon integrations, you must also configure [credentials](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html#credentials) to allow API Gateway to call the integrated actions. You can create a new or choose an existing IAM role for API Gateway to call the action and then specify the role using its ARN. The following shows an example of this ARN: 

```
arn:aws:iam::account-id:role/iam-role-name
```

This IAM role must contain a policy to allow the action to be executed. It must also have API Gateway declared (in the role's trust relationship) as a trusted entity to assume the role. Such permissions can be granted on the action itself. They are known as resource-based permissions. For the Lambda integration, you can call the Lambda's [addPermission](https://docs.amazonaws.cn/lambda/latest/dg/API_AddPermission.html) action to set the resource-based permissions and then set `credentials` to null in the API Gateway integration request.

We discussed the basic integration setup. Advanced settings involve mapping method request data to the integration request data. For more information, see [Data transformations for REST APIs in API Gateway](rest-api-data-transformations.md).

# Choose an API Gateway API integration type
Choose an API integration type



 You choose an API integration type according to the types of integration endpoint you work with and how you want data to pass to and from the integration endpoint. For a Lambda function, you can have the Lambda proxy integration, or the Lambda custom integration. For an HTTP endpoint, you can have the HTTP proxy integration or the HTTP custom integration. For an Amazon service action, you have the Amazon integration of the non-proxy type only. API Gateway also supports the mock integration, where API Gateway serves as an integration endpoint to respond to a method request.

The Lambda custom integration is a special case of the Amazon integration, where the integration endpoint corresponds to the [function-invoking action ](https://docs.amazonaws.cn/lambda/latest/dg/API_Invoke.html)of the Lambda service. 

Programmatically, you choose an integration type by setting the [https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html#type](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html#type) property on the [https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource. For the Lambda proxy integration, the value is `AWS_PROXY`. For the Lambda custom integration and all other Amazon integrations, it is `AWS`. For the HTTP proxy integration and HTTP integration, the value is `HTTP_PROXY` and `HTTP`, respectively. For the mock integration, the `type` value is `MOCK`.

The Lambda proxy integration supports a streamlined integration setup with a single Lambda function. The setup is simple and can evolve with the backend without having to tear down the existing setup. For these reasons, it is highly recommended for integration with a Lambda function. 

In contrast, the Lambda custom integration allows for reuse of configured mapping templates for various integration endpoints that have similar requirements of the input and output data formats. The setup is more involved and is recommended for more advanced application scenarios. 

Similarly, the HTTP proxy integration has a streamlined integration setup and can evolve with the backend without having to tear down the existing setup. The HTTP custom integration is more involved to set up, but allows for reuse of configured mapping templates for other integration endpoints. 

The following list summarizes the supported integration types:
+ `AWS`: This type of integration lets an API expose Amazon service actions. In `AWS` integration, you must configure both the integration request and integration response and set up necessary data mappings from the method request to the integration request, and from the integration response to the method response.
+  `AWS_PROXY`: This type of integration lets an API method be integrated with the Lambda function invocation action with a flexible, versatile, and streamlined integration setup. This integration relies on direct interactions between the client and the integrated Lambda function. 

  With this type of integration, also known as the Lambda proxy integration, you do not set the integration request or the integration response. API Gateway passes the incoming request from the client as the input to the backend Lambda function. The integrated Lambda function takes the [input of this format](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format) and parses the input from all available sources, including request headers, URL path variables, query string parameters, and applicable body. The function returns the result following this [output format](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format). 

  This is the preferred integration type to call a Lambda function through API Gateway and is not applicable to any other Amazon service actions, including Lambda actions other than the function-invoking action. 
+ `HTTP`: This type of integration lets an API expose HTTP endpoints in the backend. With the `HTTP` integration, also known as the HTTP custom integration, you must configure both the integration request and integration response. You must set up necessary data mappings from the method request to the integration request, and from the integration response to the method response.
+  `HTTP_PROXY`: The HTTP proxy integration allows a client to access the backend HTTP endpoints with a streamlined integration setup on single API method. You do not set the integration request or the integration response. API Gateway passes the incoming request from the client to the HTTP endpoint and passes the outgoing response from the HTTP endpoint to the client. 
+ `MOCK`: This type of integration lets API Gateway return a response without sending the request further to the backend. This is useful for API testing because it can be used to test the integration set up without incurring charges for using the backend and to enable collaborative development of an API. 

  In collaborative development, a team can isolate their development effort by setting up simulations of API components owned by other teams by using the `MOCK` integrations. It is also used to return CORS-related headers to ensure that the API method permits CORS access. In fact, the API Gateway console integrates the `OPTIONS` method to support CORS with a mock integration. [Gateway responses](api-gateway-gatewayResponse-definition.md#customize-gateway-responses) are other examples of mock integrations.

# Set up a proxy integration with a proxy resource
Set up proxy integrations with a proxy resource

To set up a proxy integration in an API Gateway API with a [proxy resource](api-gateway-method-settings-method-request.md#api-gateway-proxy-resource), you perform the following tasks: 
+ Create a proxy resource with a greedy path variable of `{proxy+}`. 
+ Set the `ANY` method on the proxy resource.
+ Integrate the resource and method with a backend using the HTTP or Lambda integration type.

**Note**  
Greedy path variables, `ANY` methods, and proxy integration types are independent features, although they are commonly used together. You can configure a specific HTTP method on a greedy resource or apply non-proxy integration types to a proxy resource.

API Gateway enacts certain restrictions and limitations when handling methods with either a Lambda proxy integration or an HTTP proxy integration. For details, see [Amazon API Gateway important notes](api-gateway-known-issues.md). 

**Note**  
 When using proxy integration with a passthrough, API Gateway returns the default `Content-Type:application/json` header if the content type of a payload is unspecified. 

A proxy resource is most powerful when it is integrated with a backend using either HTTP proxy integration or Lambda proxy [integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html).

## HTTP proxy integration with a proxy resource


The HTTP proxy integration, designated by `HTTP_PROXY` in the API Gateway REST API, is for integrating a method request with a backend HTTP endpoint. With this integration type, API Gateway simply passes the entire request and response between the frontend and the backend, subject to certain [restrictions and limitations](api-gateway-known-issues.md).

**Note**  
HTTP proxy integration supports multi-valued headers and query strings.

When applying the HTTP proxy integration to a proxy resource, you can set up your API to expose a portion or an entire endpoint hierarchy of the HTTP backend with a single integration setup. For example, suppose the backend of the website is organized into multiple branches of tree nodes off the root node (`/site`) as: `/site/a0/a1/.../aN`, `/site/b0/b1/.../bM`, etc. If you integrate the `ANY` method on a proxy resource of `/api/{proxy+}` with the backend endpoints with URL paths of `/site/{proxy}`, a single integration request can support any HTTP operations (GET, POST, etc.) on any of `[a0, a1, ..., aN, b0, b1, ...bM, ...]`. If you apply a proxy integration to a specific HTTP method, for example, `GET`, instead, the resulting integration request works with the specified (that is, `GET`) operations on any of those backend nodes. 

## Lambda proxy integration with a proxy resource


The Lambda proxy integration, designated by `AWS_PROXY` in the API Gateway REST API, is for integrating a method request with a Lambda function in the backend. With this integration type, API Gateway applies a default mapping template to send the entire request to the Lambda function and transforms the output from the Lambda function to HTTP responses. 

Similarly, you can apply the Lambda proxy integration to a proxy resource of `/api/{proxy+}` to set up a single integration to have a backend Lambda function react individually to changes in any of the API resources under `/api`. 

# Set up an API integration request using the API Gateway console
Set up integration request using the console

 An API method setup defines the method and describes its behaviors. To set up a method, you must specify a resource, including the root ("/"), on which the method is exposed, an HTTP method (`GET`, `POST`, etc.), and how it will be integrated with the targeted backend. The method request and response specify the contract with the calling app, stipulating which parameters the API can receive and what the response looks like. 

 The following procedures describe how to use the API Gateway console to create an integration request.

**Topics**
+ [

## Set up a Lambda integration
](#how-to-method-settings-console-lambda)
+ [

## Set up an HTTP integration
](#how-to-method-settings-console-http)
+ [

## Set up an Amazon service integration
](#how-to-method-settings-console-aws)
+ [

## Set up a mock integration
](#how-to-method-settings-console-mock)

## Set up a Lambda integration


Use a Lambda function integration to integrate your API with a Lambda function. At the API level, this is an `Amazon` integration type if you create a non-proxy integration, or an `AWS_PROXY` integration type if you create a proxy integration.

**To set up a Lambda integration**

1. In the **Resources** pane, choose **Create method**.

1. For **Method type**, select an HTTP method.

1. For **Integration type**, choose **Lambda function**.

1. To use a Lambda proxy integration, turn on **Lambda proxy integration**. To learn more about Lambda proxy integrations, see [Understand API Gateway Lambda proxy integration](set-up-lambda-proxy-integrations.md#api-gateway-create-api-as-simple-proxy).

1. For **Lambda function**, enter the name of the Lambda function.

    If you are using a Lambda function in a different Region than your API, select the Region from the dropdown menu and enter the name of the Lambda function. If you are using a cross-account Lambda function, enter the function ARN. 

1. To use the default timeout value of 29 seconds, keep **Default timeout** turned on. To set a custom timeout, choose **Default timeout** and enter a timeout value between `50` and `29000` milliseconds.

1. (Optional) You can configure the method request settings using the following dropdown menus. Choose **Method request settings** and configure your method request. For more information, see step 3 of [Edit an API Gateway method request in the API Gateway console](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console).

   You can also configure your method request settings after you create your method.

1. Choose **Create method**.

## Set up an HTTP integration


Use an HTTP integration to integrate your API with an HTTP endpoint. At the API level, this is the `HTTP` integration type.

**To set up an HTTP integration**

1. In the **Resources** pane, choose **Create method**.

1. For **Method type**, select an HTTP method.

1. For **Integration type**, choose **HTTP**.

1. To use an HTTP proxy integration, turn on **HTTP proxy integration**. To learn more about HTTP proxy integrations, see [Set up HTTP proxy integrations in API Gateway](setup-http-integrations.md#api-gateway-set-up-http-proxy-integration-on-proxy-resource).

1. For **HTTP method**, choose the HTTP method type that most closely matches the method in the HTTP backend.

1. For **Endpoint URL**, enter the URL of the HTTP backend you want this method to use.

1. For **Content handling**, select a content handling behavior.

1. To use the default timeout value of 29 seconds, keep **Default timeout** turned on. To set a custom timeout, choose **Default timeout** and enter a timeout value between `50` and `29000` milliseconds.

1. (Optional) You can configure the method request settings using the following dropdown menus. Choose **Method request settings** and configure your method request. For more information, see step 3 of [Edit an API Gateway method request in the API Gateway console](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console).

   You can also configure your method request settings after you create your method.

1. Choose **Create method**.

## Set up an Amazon service integration


Use an Amazon service integration to integrate your API directly with an Amazon service. At the API level, this is the `Amazon` integration type.

To set up an API Gateway API to do any of the following:
+ Create a new Lambda function.
+ Set a resource permission on the Lambda function.
+ Perform any other Lambda service actions.

You must choose **Amazon service**.

**To set up an Amazon service integration**

1. In the **Resources** pane, choose **Create method**.

1. For **Method type**, select an HTTP method.

1. For **Integration type**, choose **Amazon service**.

1. For **Amazon Region**, choose the Amazon Region you want this method to use to call the action.

1. For **Amazon service**, choose the Amazon service you want this method to call.

1.  For **Amazon subdomain**, enter the subdomain used by the Amazon service. Typically, you would leave this blank. Some Amazon services can support subdomains as part of the hosts. Consult the service documentation for the availability and, if available, details. 

1. For **HTTP method**, choose the HTTP method type that corresponds to the action. For HTTP method type, see the API reference documentation for the Amazon service you chose for **Amazon service**.

1. For **Action type**, select to either **Use action name** to use an API action or **Use path override** to use a custom resource path. For available actions and custom resource paths, see the API reference documentation for the Amazon service you chose for **Amazon service**.

1. Enter either an **Action name** or **Path override**.

1. For **Execution role**, enter the ARN of the IAM role that the method will use to call the action.

   To create the IAM role, you can adapt the instructions in [Step 1: Create the Amazon service proxy execution role](getting-started-aws-proxy.md#getting-started-aws-proxy-add-roles). Specify an access policy with the desired number of action and resource statements. For more information, see [How Amazon API Gateway works with IAM](security_iam_service-with-iam.md).

   For the action and resource statement syntax, see the documentation for the Amazon service you chose for **Amazon service**.

   For the IAM role's trust relationship, specify the following, which enables API Gateway to take action on behalf of your Amazon account:

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": {
           "Service": "apigateway.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. To use the default timeout value of 29 seconds, keep **Default timeout** turned on. To set a custom timeout, choose **Default timeout** and enter a timeout value between `50` and `29000` milliseconds.

1. (Optional) You can configure the method request settings using the following dropdown menus. Choose **Method request settings** and configure your method request. For more information, see step 3 of [Edit an API Gateway method request in the API Gateway console](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console).

   You can also configure your method request settings after you create your method.

1. Choose **Create method**.

## Set up a mock integration


 Use a mock integration if you want API Gateway to act as your backend to return static responses. At the API level, this is the `MOCK` integration type. Typically, you can use the `MOCK` integration when your API is not yet final, but you want to generate API responses to unblock dependent teams for testing. For the `OPTION` method, API Gateway sets the `MOCK` integration as default to return CORS-enabling headers for the applied API resource.

**To set up a mock integration**

1. In the **Resources** pane, choose **Create method**.

1. For **Method type**, select an HTTP method.

1. For **Integration type**, choose **Mock**.

1. (Optional) You can configure the method request settings using the following dropdown menus. Choose **Method request settings** and configure your method request. For more information, see step 3 of [Edit an API Gateway method request in the API Gateway console](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console).

   You can also configure your method request settings after you create your method.

1. Choose **Create method**.

# Set up an integration response in API Gateway
Integration response

 For a non-proxy integration, you must set up at least one integration response, and make it the default response, to pass the result returned from the backend to the client. You can choose to pass through the result as-is or to transform the integration response data to the method response data if the two have different formats. 

For a proxy integration, API Gateway automatically passes the backend output to the client as an HTTP response. You do not set either an integration response or a method response.

To set up an integration response, you perform the following required and optional tasks:

1.  Specify an HTTP status code of a method response to which the integration response data is mapped. This is required.

1.  Define a regular expression to select backend output to be represented by this integration response. If you leave this empty, the response is the default response that is used to catch any response not yet configured.

1.  If needed, declare mappings consisting of key-value pairs to map specified integration response parameters to given method response parameters.

1. If needed, add body-mapping templates to transform given integration response payloads into specified method response payloads.

1.  If needed, specify how to handle type conversion for a binary payload.

An integration response is an HTTP response encapsulating the backend response. For an HTTP endpoint, the backend response is an HTTP response. The integration response status code can take the backend-returned status code, and the integration response body is the backend-returned payload. For a Lambda endpoint, the backend response is the output returned from the Lambda function. With the Lambda integration, the Lambda function output is returned as a `200 OK` response. The payload can contain the result as JSON data, including a JSON string or a JSON object, or an error message as a JSON object. You can assign a regular expression to the [selectionPattern](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern) property to map an error response to an appropriate HTTP error response. For more information about the Lambda function error response, see [Handle Lambda errors in API Gateway](handle-errors-in-lambda-integration.md). With the Lambda proxy integration, the Lambda function must return output of the following format:

```
{
    statusCode: "...",            // a valid HTTP status code
    headers: { 
        custom-header: "..."      // any API-specific custom header
    },
    body: "...",                  // a JSON string.
    isBase64Encoded:  true|false  // for binary support
}
```

There is no need to map the Lambda function response to its proper HTTP response.

To return the result to the client, set up the integration response to pass the endpoint response through as-is to the corresponding method response. Or you can map the endpoint response data to the method response data. The response data that can be mapped includes the response status code, response header parameters, and response body. If no method response is defined for the returned status code, API Gateway returns a 500 error. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md).



# Lambda integrations for REST APIs in API Gateway
Lambda integration

 You can integrate an API method with a Lambda function using Lambda proxy integration or Lambda non-proxy (custom) integration. 

In Lambda proxy integration, the required setup is simple. Set the integration's HTTP method to POST, the integration endpoint URI to the ARN of the Lambda function invocation action of a specific Lambda function, and grant API Gateway permission to call the Lambda function on your behalf.

In Lambda non-proxy integration, in addition to the proxy integration setup steps, you also specify how the incoming request data is mapped to the integration request and how the resulting integration response data is mapped to the method response. 

**Topics**
+ [

# Lambda proxy integrations in API Gateway
](set-up-lambda-proxy-integrations.md)
+ [

# Set up Lambda custom integrations in API Gateway
](set-up-lambda-custom-integrations.md)
+ [

# Set up asynchronous invocation of the backend Lambda function
](set-up-lambda-integration-async.md)
+ [

# Handle Lambda errors in API Gateway
](handle-errors-in-lambda-integration.md)

# Lambda proxy integrations in API Gateway
Lambda proxy integrations

The following section shows how to use a Lambda proxy integration.

**Topics**
+ [

## Understand API Gateway Lambda proxy integration
](#api-gateway-create-api-as-simple-proxy)
+ [

## Support for multi-value headers and query string parameters
](#apigateway-multivalue-headers-and-parameters)
+ [

## Input format of a Lambda function for proxy integration
](#api-gateway-simple-proxy-for-lambda-input-format)
+ [

## Output format of a Lambda function for proxy integration
](#api-gateway-simple-proxy-for-lambda-output-format)
+ [

# Set up Lambda proxy integration for API Gateway using the Amazon CLI
](set-up-lambda-proxy-integration-using-cli.md)
+ [

# Set up a proxy resource with Lambda proxy integration with an OpenAPI definition
](api-gateway-set-up-lambda-proxy-integration-on-proxy-resource.md)

## Understand API Gateway Lambda proxy integration
Understand Lambda proxy integration

Amazon API Gateway Lambda proxy integration is a simple, powerful, and nimble mechanism to build an API with a setup of a single API method. The Lambda proxy integration allows the client to call a single Lambda function in the backend. The function accesses many resources or features of other Amazon services, including calling other Lambda functions. 

 In Lambda proxy integration, when a client submits an API request, API Gateway passes to the integrated Lambda function an [event object](#api-gateway-simple-proxy-for-lambda-input-format), except that the order of the request parameters is not preserved. This [request data](#api-gateway-simple-proxy-for-lambda-input-format) includes the request headers, query string parameters, URL path variables, payload, and API configuration data. The configuration data can include current deployment stage name, stage variables, user identity, or authorization context (if any). The backend Lambda function parses the incoming request data to determine the response that it returns. For API Gateway to pass the Lambda output as the API response to the client, the Lambda function must return the result in [this format](#api-gateway-simple-proxy-for-lambda-output-format). 

 Because API Gateway doesn't intervene very much between the client and the backend Lambda function for the Lambda proxy integration, the client and the integrated Lambda function can adapt to changes in each other without breaking the existing integration setup of the API. To enable this, the client must follow application protocols enacted by the backend Lambda function. 

 You can set up a Lambda proxy integration for any API method. But a Lambda proxy integration is more potent when it is configured for an API method involving a generic proxy resource. The generic proxy resource can be denoted by a special templated path variable of `{proxy+}`, the catch-all `ANY` method placeholder, or both. The client can pass the input to the backend Lambda function in the incoming request as request parameters or applicable payload. The request parameters include headers, URL path variables, query string parameters, and the applicable payload. The integrated Lambda function verifies all of the input sources before processing the request and responding to the client with meaningful error messages if any of the required input is missing.

 When calling an API method integrated with the generic HTTP method of `ANY` and the generic resource of `{proxy+}`, the client submits a request with a particular HTTP method in place of `ANY`. The client also specifies a particular URL path instead of `{proxy+}`, and includes any required headers, query string parameters, or an applicable payload. 

 The following list summarizes runtime behaviors of different API methods with the Lambda proxy integration: 
+ `ANY /{proxy+}`: The client must choose a particular HTTP method, must set a particular resource path hierarchy, and can set any headers, query string parameters, and applicable payload to pass the data as input to the integrated Lambda function. 
+ `ANY /res`: The client must choose a particular HTTP method and can set any headers, query string parameters, and applicable payload to pass the data as input to the integrated Lambda function. 
+ `GET|POST|PUT|... /{proxy+}`: The client can set a particular resource path hierarchy, any headers, query string parameters, and applicable payload to pass the data as input to the integrated Lambda function. 
+  `GET|POST|PUT|... /res/{path}/...`: The client must choose a particular path segment (for the `{path}` variable) and can set any request headers, query string parameters, and applicable payload to pass input data to the integrated Lambda function.
+  `GET|POST|PUT|... /res`: The client can choose any request headers, query string parameters, and applicable payload to pass input data to the integrated Lambda function.

 Both the proxy resource of `{proxy+}` and the custom resource of `{custom}` are expressed as templated path variables. However `{proxy+}` can refer to any resource along a path hierarchy, while `{custom}` refers to a particular path segment only. For example, a grocery store might organize its online product inventory by department names, produce categories, and product types. The grocery store's website can then represent available products by the following templated path variables of custom resources: `/{department}/{produce-category}/{product-type}`. For example, apples are represented by `/produce/fruit/apple` and carrots by `/produce/vegetables/carrot`. It can also use `/{proxy+}` to represent any department, any produce category, or any product type that a customer can search for while shopping in the online store. For example, `/{proxy+}` can refer to any of the following items: 
+ `/produce`
+ `/produce/fruit`
+ `/produce/vegetables/carrot`

 To let customers search for any available product, its produce category, and the associated store department, you can expose a single method of `GET /{proxy+}` with read-only permissions. Similarly, to allow a supervisor to update the `produce` department's inventory, you can set up another single method of `PUT /produce/{proxy+}` with read/write permissions. To allow a cashier to update the running total of a vegetable, you can set up a `POST /produce/vegetables/{proxy+}` method with read/write permissions. To let a store manager perform any possible action on any available product, the online store developer can expose the `ANY /{proxy+}` method with read/write permissions. In any case, at run time, the customer or the employee must select a particular product of a given type in a chosen department, a specific produce category in a chosen department, or a specific department. 



For more information about setting up API Gateway proxy integrations, see [Set up a proxy integration with a proxy resource](api-gateway-set-up-simple-proxy.md). 

 Proxy integration requires that the client have more detailed knowledge of the backend requirements. Therefore, to ensure optimal app performance and user experience, the backend developer must communicate clearly to the client developer the requirements of the backend, and provide a robust error feedback mechanism when the requirements are not met. 

## Support for multi-value headers and query string parameters


API Gateway supports multiple headers and query string parameters that have the same name. Multi-value headers as well as single-value headers and parameters can be combined in the same requests and responses. For more information, see [Input format of a Lambda function for proxy integration](#api-gateway-simple-proxy-for-lambda-input-format) and [Output format of a Lambda function for proxy integration](#api-gateway-simple-proxy-for-lambda-output-format).

## Input format of a Lambda function for proxy integration


In Lambda proxy integration, API Gateway maps the entire client request to the input `event` parameter of the backend Lambda function. The following example shows the structure of an event that API Gateway sends to a Lambda proxy integration.

In this example, we assume that the invocation to API Gateway was the following:

```
curl 'https://a1b2c3.execute-api.us-east-1.amazonaws.com/my/path?parameter1=value1&parameter2=value1&parameter2=value2&parameter3=value1,value2' -H 'header1: value1' -H 'header2: value1' -H 'header2: value2' -H 'header3: value1,value2'
```

The output looks like the following:

```
{
  "resource": "/my/path",
  "path": "/my/path",
  "httpMethod": "GET",
  "headers": {
      "header1": "value1",
      "header2": "value2",
      "header3": "value1,value2"
  },
  "multiValueHeaders": {
    "header1": ["value1"],
    "header2": ["value1","value2"],
    "header3": ["value1,value2"]
  },
  "queryStringParameters": {
      "parameter1": "value1",
      "parameter2": "value2",
      "parameter3": "value1,value2"
  },
  "multiValueQueryStringParameters": {
    "parameter1": ["value1"],
    "parameter2": ["value1","value2"],
    "parameter3": ["value1,value2"]
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "id",
    "authorizer": {
      "claims": null,
      "scopes": null
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "extendedRequestId": "request-id",
    "httpMethod": "GET",
    "identity": {
      "accessKey": null,
      "accountId": null,
      "caller": null,
      "cognitoAuthenticationProvider": null,
      "cognitoAuthenticationType": null,
      "cognitoIdentityId": null,
      "cognitoIdentityPoolId": null,
      "principalOrgId": null,
      "sourceIp": "IP",
      "user": null,
      "userAgent": "user-agent",
      "userArn": null,
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "path": "/my/path",
    "protocol": "HTTP/1.1",
    "requestId": "id=",
    "requestTime": "04/Mar/2020:19:15:17 +0000",
    "requestTimeEpoch": 1583349317135,
    "resourceId": null,
    "resourcePath": "/my/path",
    "stage": "$default"
  },
  "pathParameters": null,
  "stageVariables": null,
  "body": "Hello from Lambda!",
  "isBase64Encoded": false
}
```

**Note**  
In the input:  
The `headers` key can only contain single-value headers.
The `multiValueHeaders` key can contain multi-value headers as well as single-value headers.
If you specify values for both `headers` and `multiValueHeaders`, API Gateway merges them into a single list. If the same key-value pair is specified in both, only the values from `multiValueHeaders` will appear in the merged list.

In the input to the backend Lambda function, the `requestContext` object is a map of key-value pairs. In each pair, the key is the name of a [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) variable property, and the value is the value of that property. API Gateway might add new keys to the map.

Depending on the features that are enabled, the `requestContext` map may vary from API to API. For example, in the preceding example, no authorization type is specified, so no `$context.authorizer.*` or `$context.identity.*` properties are present. When an authorization type is specified, this causes API Gateway to pass authorized user information to the integration endpoint in a `requestContext.identity` object as follows:
+ When the authorization type is `AWS_IAM`, the authorized user information includes `$context.identity.*` properties.
+ When the authorization type is `COGNITO_USER_POOLS` (Amazon Cognito authorizer), the authorized user information includes `$context.identity.cognito*` and `$context.authorizer.claims.*` properties.
+ When the authorization type is `CUSTOM` (Lambda authorizer), the authorized user information includes `$context.authorizer.principalId` and other applicable `$context.authorizer.*` properties.

## Output format of a Lambda function for proxy integration


In Lambda proxy integration, API Gateway requires the backend Lambda function to return output according to the following JSON format:

```
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": "..."
}
```

In the output:
+ The `headers` and `multiValueHeaders` keys can be unspecified if no extra response headers are to be returned.
+ The `headers` key can only contain single-value headers.
+ The `multiValueHeaders` key can contain multi-value headers as well as single-value headers. You can use the `multiValueHeaders` key to specify all of your extra headers, including any single-value ones.
+ If you specify values for both `headers` and `multiValueHeaders`, API Gateway merges them into a single list. If the same key-value pair is specified in both, only the values from `multiValueHeaders` will appear in the merged list.

To enable CORS for the Lambda proxy integration, you must add `Access-Control-Allow-Origin:domain-name` to the output `headers`. `domain-name` can be `*` for any domain name. The output `body` is marshalled to the frontend as the method response payload. If `body` is a binary blob, you can encode it as a Base64-encoded string by setting `isBase64Encoded` to `true` and configuring `*/*` as a **Binary Media Type**. Otherwise, you can set it to `false` or leave it unspecified.

**Note**  
For more information about enabling binary support, see [Enabling binary support using the API Gateway console](api-gateway-payload-encodings-configure-with-console.md). For an example Lambda function, see [Return binary media from a Lambda proxy integration in API Gateway](lambda-proxy-binary-media.md).

If the function output is of a different format, API Gateway returns a `502 Bad Gateway` error response. 

To return a response in a Lambda function in Node.js, you can use commands such as the following:
+ To return a successful result, call `callback(null, {"statusCode": 200, "body": "results"})`.
+ To throw an exception, call `callback(new Error('internal server error'))`.
+ For a client-side error (if, for example, a required parameter is missing), you can call `callback(null, {"statusCode": 400, "body": "Missing parameters of ..."})` to return the error without throwing an exception.

In a Lambda `async` function in Node.js, the equivalent syntax would be:
+ To return a successful result, call `return {"statusCode": 200, "body": "results"}`.
+ To throw an exception, call `throw new Error("internal server error")`.
+ For a client-side error (if, for example, a required parameter is missing), you can call `return {"statusCode": 400, "body": "Missing parameters of ..."}` to return the error without throwing an exception.

# Set up Lambda proxy integration for API Gateway using the Amazon CLI


In this section, we show how to set up an API with the Lambda proxy integration using the Amazon CLI. For detailed instructions for using the API Gateway console to configure a proxy resource with the Lambda proxy integration, see [Tutorial: Create a REST API with a Lambda proxy integration](api-gateway-create-api-as-simple-proxy-for-lambda.md).

As an example, we use the following sample Lambda function as the backend of the API:

```
export const handler = async(event, context) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    var res ={
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    };
    var greeter = 'World';
    if (event.greeter && event.greeter!=="") {
        greeter =  event.greeter;
    } else if (event.body && event.body !== "") {
        var body = JSON.parse(event.body);
        if (body.greeter && body.greeter !== "") {
            greeter = body.greeter;
        }
    } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
        greeter = event.queryStringParameters.greeter;
    } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
        greeter = event.multiValueHeaders.greeter.join(" and ");
    } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
        greeter = event.headers.greeter;
    } 
    res.body = "Hello, " + greeter + "!";
    return res
};
```

Comparing this to the Lambda custom integration setup in [Set up Lambda custom integrations in API Gateway](set-up-lambda-custom-integrations.md), the input to this Lambda function can be expressed in the request parameters and body. You have more latitude to allow the client to pass the same input data. Here, the client can pass the greeter's name in as a query string parameter, a header, or a body property. The function can also support the Lambda custom integration. The API setup is simpler. You do not configure the method response or integration response at all.

**To set up a Lambda proxy integration using the Amazon CLI**

1. Use the following [create-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-rest-api.html) command to create an API:

   ```
   aws apigateway create-rest-api --name 'HelloWorld (Amazon CLI)'
   ```

   The output will look like the following:

   ```
   {
       "name": "HelloWorldProxy (Amazon CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   You use the API `id` (`te6si5ach7`) and the `rootResourceId` ( `krznpq9xpg`) throughout this example.

1. Use the following [create-resource](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-resource.html) command to create an API Gateway [Resource](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html) of `/greeting`:

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part {proxy+}
   ```

   The output will look like the following:

   ```
   {
       "path": "/{proxy+}", 
       "pathPart": "{proxy+}", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   You use the `{proxy+}` resource's `id` value (`2jf6xt`) to create a method on the `/{proxy+}` resource in the next step.

1. Use the following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) to create an `ANY` method request of `ANY /{proxy+}`:

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method ANY \
          --authorization-type "NONE"
   ```

   The output will look like the following:

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "ANY", 
       "authorizationType": "NONE"
   }
   ```

   This API method allows the client to receive or send greetings from the Lambda function at the backend. 

1. Use the following [put-integration](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-integration.html) command to set up the integration of the `ANY /{proxy+}` method with a Lambda function, named `HelloWorld`. This function responds to the request with a message of `"Hello, {name}!"`, if the `greeter` parameter is provided, or `"Hello, World!"`, if the query string parameter is not set.

   ```
   aws apigateway put-integration \
         --rest-api-id te6si5ach7 \
         --resource-id 2jf6xt \
         --http-method ANY \
         --type AWS_PROXY \
         --integration-http-method POST \
         --uri arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:HelloWorld/invocations \
         --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```
**Important**  
For Lambda integrations, you must use the HTTP method of `POST` for the integration request, according to the [specification of the Lambda service action for function invocations](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html). The IAM role of `apigAwsProxyRole` must have policies allowing the `apigateway` service to invoke Lambda functions. For more information about IAM permissions, see [API Gateway permissions model for invoking an API](permissions.md#api-gateway-control-access-iam-permissions-model-for-calling-api).

   The output will look like the following:

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:1234567890:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "cacheNamespace": "vvom7n", 
       "credentials": "arn:aws:iam::1234567890:role/apigAwsProxyRole", 
       "type": "AWS_PROXY"
   }
   ```

   Instead of supplying an IAM role for `credentials`, you can use the [add-permission](https://docs.amazonaws.cn/cli/latest/reference/lambda/add-permission.html) command to add resource-based permissions. This is what the API Gateway console does. 

1. Use the following [create-deployment](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-deployment.html) command to deploy the API to a `test` stage:

   ```
   aws apigateway create-deployment  \
         --rest-api-id te6si5ach7 \
         --stage-name test
   ```

1. Test the API using the following cURL commands in a terminal.

   Calling the API with the query string parameter of `?greeter=jane`:

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=jane'
   ```

   Calling the API with a header parameter of `greeter:jane`:

   ```
   curl -X GET https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -H 'greeter: jane'
   ```

   Calling the API with a body of `{"greeter":"jane"}`:

   ```
   curl -X POST https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -d '{ "greeter": "jane" }'
   ```

   In all the cases, the output is a 200 response with the following response body:

   ```
   Hello, jane!
   ```

# Set up a proxy resource with Lambda proxy integration with an OpenAPI definition


To set up a proxy resource with the Lambda proxy integration type, create an API resource with a greedy path parameter (for example, `/parent/{proxy+}`) and integrate this resource with a Lambda function backend (for example, `arn:aws:lambda:us-west-2:123456789012:function:SimpleLambda4ProxyResource`) on the `ANY` method. The greedy path parameter must be at the end of the API resource path. As with a non-proxy resource, you can set up the proxy resource by using the API Gateway console, importing an OpenAPI definition file, or calling the API Gateway REST API directly.

The following OpenAPI API definition file shows an example of an API with a proxy resource that is integrated with a Lambda function named `SimpleLambda4ProxyResource`.

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

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-09-12T17:50:37Z",
      "title": "ProxyIntegrationWithLambda"
   },
   "paths": {
      "/{proxy+}": {
         "x-amazon-apigateway-any-method": {
            "parameters": [
               {
                  "name": "proxy",
                  "in": "path",
                  "required": true,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {},
            "x-amazon-apigateway-integration": {
               "responses": {
                  "default": {
                     "statusCode": "200"
                  }
               },
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "POST",
               "cacheNamespace": "roq9wj",
               "cacheKeyParameters": [
                  "method.request.path.proxy"
               ],
               "type": "aws_proxy"
            }
         }
      }
   },
   "servers": [
      {
         "url": "https://gy415nuibc.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/testStage"
            }
         }
      }
   ]
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-09-12T17:50:37Z",
    "title": "ProxyIntegrationWithLambda"
  },
  "host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
  "basePath": "/testStage",
  "schemes": [
    "https"
  ],
  "paths": {
    "/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {},
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "cacheNamespace": "roq9wj",
          "cacheKeyParameters": [
            "method.request.path.proxy"
          ],
          "type": "aws_proxy"
        }
      }
    }
  }
}
```

------

In Lambda proxy integration, at run time, API Gateway maps an incoming request into the input `event` parameter of the Lambda function. The input includes the request method, path, headers, any query string parameters, any payload, associated context, and any defined stage variables. The input format is explained in [Input format of a Lambda function for proxy integration](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format). For API Gateway to map the Lambda output to HTTP responses successfully, the Lambda function must output the result in the format described in [Output format of a Lambda function for proxy integration](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format). 

In Lambda proxy integration of a proxy resource through the `ANY` method, the single backend Lambda function serves as the event handler for all requests through the proxy resource. For example, to log traffic patterns, you can have a mobile device send its location information of state, city, street, and building by submitting a request with `/state/city/street/house` in the URL path for the proxy resource. The backend Lambda function can then parse the URL path and insert the location tuples into a DynamoDB table.

# Set up Lambda custom integrations in API Gateway
Set up Lambda custom integrations

 To show how to set up the Lambda custom, or non-proxy,integration, we create an API Gateway API to expose the `GET /greeting?greeter={name}` method to invoke a Lambda function. Use one of the following example Lambda functions for you API.

Use one of the following example Lambda functions:

------
#### [ Node.js ]

```
'use strict';
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];            
var times = ['morning', 'afternoon', 'evening', 'night', 'day'];

export const handler = async(event) => {
  console.log(event);
  // Parse the input for the name, city, time and day property values
  let name = event.name === null || event.name === undefined || event.name === "" ? 'you' : event.name;
  let city = event.city === undefined ? 'World' : event.city;
  let time = times.indexOf(event.time)<0 ? 'day' : event.time;
  let day = days.indexOf(event.day)<0 ? null : event.day;

  // Generate a greeting
  let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
  if (day) greeting += 'Happy ' + day + '!';
  
  // Log the greeting to CloudWatch
  console.log('Hello: ', greeting);
  
  // Return a greeting to the caller
  return greeting;
};
```

------
#### [ Python ]

```
import json


def lambda_handler(event, context):
    print(event)
    res = {
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    }

    if event['greeter'] == "":
        res['body'] = "Hello, World"
    elif (event['greeter']):
        res['body'] = "Hello, " + event['greeter'] + "!"
    else:
        raise Exception('Missing the required greeter parameter.')

    return res
```

------

The function responds with a message of `"Hello, {name}!"` if the `greeter` parameter value is a non-empty string. It returns a message of `"Hello, World!"` if the `greeter` value is an empty string. The function returns an error message of `"Missing the required greeter parameter."` if the greeter parameter is not set in the incoming request. We name the function `HelloWorld`.

You can create it in the Lambda console or by using the Amazon CLI. In this section, we reference this function using the following ARN:

```
arn:aws:lambda:us-east-1:123456789012:function:HelloWorld
```

With the Lambda function set in the backend, proceed to set up the API.<a name="set-up-lambda-custom-integration-using-cli"></a>

**To set up the Lambda custom integration using the Amazon CLI**

1. Use the following [create-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-rest-api.html) command to create an API:

   ```
   aws apigateway create-rest-api --name 'HelloWorld (Amazon CLI)'
   ```

   The output will look like the following:

   ```
   {
       "name": "HelloWorld (Amazon CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   You use the API `id` ( `te6si5ach7`) and the `rootResourceId` (`krznpq9xpg`) throughout this example.

1. Use the following [create-resource](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-resource.html) command to create an API Gateway [Resource](https://docs.amazonaws.cn/apigateway/latest/api/API_Resource.html) of `/greeting`:

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part greeting
   ```

   The output will look like the following:

   ```
   {
       "path": "/greeting", 
       "pathPart": "greeting", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   You use the `greeting` resource's `id` value (`2jf6xt`) to create a method on the `/greeting` resource in the next step.

1. Use the following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command to create an API method request of `GET /greeting?greeter={name}`:

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method GET \
          --authorization-type "NONE" \
          --request-parameters method.request.querystring.greeter=false
   ```

   The output will look like the following:

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "GET", 
       "authorizationType": "NONE", 
       "requestParameters": {
           "method.request.querystring.greeter": false
       }
   }
   ```

   This API method allows the client to receive a greeting from the Lambda function at the backend. The `greeter` parameter is optional because the backend should handle either an anonymous caller or a self-identified caller.

1. Use the following [put-method-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method-response.html) command to set up the `200 OK` response to the method request of `GET /greeting?greeter={name}`:

   ```
   aws apigateway put-method-response \
           --rest-api-id te6si5ach7 \ 
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200
   ```

   

1. Use the following [put-integration](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-integration.html) command to set up the integration of the `GET /greeting?greeter={name}` method with a Lambda function, named `HelloWorld`. The function responds to the request with a message of `"Hello, {name}!"`, if the `greeter` parameter is provided, or `"Hello, World!"`, if the query string parameter is not set.

   ```
   aws apigateway put-integration \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --type Amazon \
           --integration-http-method POST \
           --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations \
           --request-templates '{"application/json":"{\"greeter\":\"$input.params('greeter')\"}"}' \
           --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```

   The mapping template supplied here translates the `greeter` query string parameter to the `greeter` property of the JSON payload. This is necessary because the input to a Lambda function must be expressed in the body.
**Important**  
For Lambda integrations, you must use the HTTP method of `POST` for the integration request, according to the [specification of the Lambda service action for function invocations](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html). The `uri` parameter is the ARN of the function-invoking action.  
The output will look like the following:

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "requestTemplates": {
           "application/json": "{\"greeter\":\"$input.params('greeter')\"}"
       }, 
       "cacheNamespace": "krznpq9xpg", 
       "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", 
       "type": "AWS"
   }
   ```

   The IAM role of `apigAwsProxyRole` must have policies that allow the `apigateway` service to invoke Lambda functions. Instead of supplying an IAM role for `credentials`, you can call the [add-permission](https://docs.amazonaws.cn/cli/latest/reference/lambda/add-permission.html) command to add resource-based permissions. This is how the API Gateway console adds these permissions. 

1. Use the following [put-integration-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-integration-response.html) command to set up the integration response to pass the Lambda function output to the client as the `200 OK` method response:

   ```
    aws apigateway put-integration-response \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200 \
           --selection-pattern ""
   ```

   By setting the selection-pattern to an empty string, the `200 OK` response is the default. 

   The output will look like the following:

   ```
    {
       "selectionPattern": "", 
       "statusCode": "200"
   }
   ```

1. Use the following [create-deployment](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-deployment.html) command to deploy the API to a `test` stage:

   ```
   aws apigateway create-deployment \
           --rest-api-id te6si5ach7 \
           --stage-name test
   ```

1.  Test the API using the following cURL command in a terminal:

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=me' \
     -H 'authorization: AWS4-HMAC-SHA256 Credential={access_key}/20171020/us-west-2/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=f327...5751'
   ```

# Set up asynchronous invocation of the backend Lambda function


In Lambda non-proxy (custom) integration, the backend Lambda function is invoked synchronously by default. This is the desired behavior for most REST API operations. Some applications, however, require work to be performed asynchronously (as a batch operation or a long-latency operation), typically by a separate backend component. In this case, the backend Lambda function is invoked asynchronously, and the front-end REST API method doesn't return the result.

You can configure the Lambda function for a Lambda non-proxy integration to be invoked asynchronously by specifying `'Event'` as the [Lambda invocation type](https://docs.amazonaws.cn/lambda/latest/dg/lambda-invocation.html). This is done as follows:

## Configure Lambda asynchronous invocation in the API Gateway console


For all invocations to be asynchronous:
+ In **Integration request**, add an `X-Amz-Invocation-Type` header with a static value of `'Event'`.

For clients to decide if invocations are asynchronous or synchronous:

1. In **Method request**, add an `InvocationType` header.

1. In **Integration request** add an `X-Amz-Invocation-Type` header with a mapping expression of `method.request.header.InvocationType`.

1. Clients can include the `InvocationType: Event` header in API requests for asynchronous invocations or `InvocationType: RequestResponse` for synchronous invocations.

## Configure Lambda asynchronous invocation using OpenAPI


For all invocations to be asynchronous:
+  Add the `X-Amz-Invocation-Type` header to the **x-amazon-apigateway-integration** section.

  ```
  "x-amazon-apigateway-integration" : {
            "type" : "aws",
            "httpMethod" : "POST",
            "uri" : "arn:aws-cn:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws-cn:lambda:us-west-2:123456789012:function:my-function/invocations",
            "responses" : {
              "default" : {
                "statusCode" : "200"
              }
            },
            "requestParameters" : {
              "integration.request.header.X-Amz-Invocation-Type" : "'Event'"
            },
            "passthroughBehavior" : "when_no_match",
            "contentHandling" : "CONVERT_TO_TEXT"
          }
  ```

For clients to decide if invocations are asynchronous or synchronous:

1.  Add the following header on any [OpenAPI Path Item Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#pathItemObject). 

   ```
   "parameters" : [ {
   "name" : "InvocationType",
   "in" : "header",
   "schema" : {
     "type" : "string"
   }
   } ]
   ```

1.  Add the `X-Amz-Invocation-Type` header to **x-amazon-apigateway-integration** section.

   ```
   "x-amazon-apigateway-integration" : {
             "type" : "aws",
             "httpMethod" : "POST",
             "uri" : "arn:aws-cn:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws-cn:lambda:us-west-2:123456789012:function:my-function/invocations",
             "responses" : {
               "default" : {
                 "statusCode" : "200"
               }
             },
             "requestParameters" : {
               "integration.request.header.X-Amz-Invocation-Type" : "method.request.header.InvocationType"
             },
             "passthroughBehavior" : "when_no_match",
             "contentHandling" : "CONVERT_TO_TEXT"
           }
   ```

1.  Clients can include the `InvocationType: Event` header in API requests for asynchronous invocations or `InvocationType: RequestResponse` for synchronous invocations. 

## Configure Lambda asynchronous invocation using Amazon CloudFormation


The following Amazon CloudFormation templates show how to configure the `AWS::ApiGateway::Method` for asynchronous invocations.

For all invocations to be asynchronous:

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: "'Event'"
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

For clients to decide if invocations are asynchronous or synchronous:

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      RequestParameters:
        method.request.header.InvocationType: false
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: method.request.header.InvocationType
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

 Clients can include the `InvocationType: Event` header in API requests for asynchronous invocations or `InvocationType: RequestResponse` for synchronous invocations. 

# Handle Lambda errors in API Gateway


 For Lambda custom integrations, you must map errors returned by Lambda in the integration response to standard HTTP error responses for your clients. Otherwise, Lambda errors are returned as `200 OK` responses by default and the result is not intuitive for your API users. 

 There are two types of errors that Lambda can return: standard errors and custom errors. In your API, you must handle these differently. 

 With the Lambda proxy integration, Lambda is required to return an output of the following format: 

```
{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}
```

In this output, `statusCode` is typically `4XX` for a client error and `5XX` for a server error. API Gateway handles these errors by mapping the Lambda error to an HTTP error response, according to the specified `statusCode`. For API Gateway to pass the error type (for example, `InvalidParameterException`), as part of the response to the client, the Lambda function must include a header (for example, `"X-Amzn-ErrorType":"InvalidParameterException"`) in the `headers` property. 

**Topics**
+ [

## Handle standard Lambda errors in API Gateway
](#handle-standard-errors-in-lambda-integration)
+ [

## Handle custom Lambda errors in API Gateway
](#handle-custom-errors-in-lambda-integration)

## Handle standard Lambda errors in API Gateway


A standard Amazon Lambda error has the following format:

```
{
  "errorMessage": "<replaceable>string</replaceable>",
  "errorType": "<replaceable>string</replaceable>",
  "stackTrace": [
    "<replaceable>string</replaceable>",
    ...
  ]
}
```

 Here, `errorMessage` is a string expression of the error. The `errorType` is a language-dependent error or exception type. The `stackTrace` is a list of string expressions showing the stack trace leading to the occurrence of the error. 

 For example, consider the following JavaScript (Node.js) Lambda function. 

```
export const handler = function(event, context, callback) {
    callback(new Error("Malformed input ..."));
};
```

This function returns the following standard Lambda error, containing `Malformed input ...` as the error message:

```
{
  "errorMessage": "Malformed input ...",
  "errorType": "Error",
  "stackTrace": [
    "export const handler (/var/task/index.js:3:14)"
  ]
}
```

 Similarly, consider the following Python Lambda function, which raises an `Exception` with the same `Malformed input ...` error message. 

```
def lambda_handler(event, context):
    raise Exception('Malformed input ...')
```

 This function returns the following standard Lambda error: 

```
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      3,
      "lambda_handler",
      "raise Exception('Malformed input ...')"
    ]
  ],
  "errorType": "Exception",
  "errorMessage": "Malformed input ..."
}
```

 Note that the `errorType` and `stackTrace` property values are language-dependent. The standard error also applies to any error object that is an extension of the `Error` object or a subclass of the `Exception` class. 

 To map the standard Lambda error to a method response, you must first decide on an HTTP status code for a given Lambda error. You then set a regular expression pattern on the `[selectionPattern](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)` property of the [IntegrationResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) associated with the given HTTP status code. In the API Gateway console, this `selectionPattern` is denoted as **Lambda error regex** in the **Integration response** section, under each integration response.

**Note**  
API Gateway uses Java pattern-style regexes for response mapping. For more information, see [Pattern](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) in the Oracle documentation.

 For example, use the following [put-integration-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-integration-response.html) to set up a new `selectionPattern` expression: 

```
aws apigateway put-integration-response --rest-api-id z0vprf0mdh --resource-id x3o5ih --http-method GET --status-code 400 --selection-pattern "Malformed.*" --region us-west-2
```

 Make sure that you also set up the corresponding error code (`400`) on the [method response](api-gateway-method-settings-method-response.md#setup-method-response-status-code). Otherwise, API Gateway throws an invalid configuration error response at runtime. 

**Note**  
 At runtime, API Gateway matches the Lambda error's `errorMessage` against the pattern of the regular expression on the `selectionPattern` property. If there is a match, API Gateway returns the Lambda error as an HTTP response of the corresponding HTTP status code. If there is no match, API Gateway returns the error as a default response or throws an invalid configuration exception if no default response is configured.   
 Setting the `selectionPattern` value to `.*` for a given response amounts to resetting this response as the default response. This is because such a selection pattern will match all error messages, including null, i.e., any unspecified error message. The resulting mapping overrides the default mapping. If you use `.+` as the selection pattern to filter responses, it might not match a response containing be aware that it may not match a response containing a newline ('`\n`) character.

 To update an existing `selectionPattern` value using the Amazon CLI, call the [update-integration-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-integration-response.html) operation to replace the `/selectionPattern` path value with the specified regex expression of the `Malformed*` pattern. 



To set the `selectionPattern` expression using the API Gateway console, enter the expression in the **Lambda error regex** text box when setting up or updating an integration response of a specified HTTP status code. 

## Handle custom Lambda errors in API Gateway


 Instead of the standard error described in the preceding section, Amazon Lambda allows you to return a custom error object as JSON string. The error can be any valid JSON object. For example, the following JavaScript (Node.js) Lambda function returns a custom error: 

```
export const handler = (event, context, callback) => {
    ...
    // Error caught here:
    var myErrorObj = {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
    callback(JSON.stringify(myErrorObj));
};
```

 You must turn the `myErrorObj` object into a JSON string before calling `callback` to exit the function. Otherwise, the `myErrorObj` is returned as a string of `"[object Object]"`. When a method of your API is integrated with the preceding Lambda function, API Gateway receives an integration response with the following payload: 

```
{
    "errorMessage": "{\"errorType\":\"InternalServerError\",\"httpStatus\":500,\"requestId\":\"e5849002-39a0-11e7-a419-5bb5807c9fb2\",\"trace\":{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}}"
}
```

 As with any integration response, you can pass through this error response as-is to the method response. Or you can have a mapping template to transform the payload into a different format. For example, consider the following body-mapping template for a method response of `500` status code: 

```
{
    errorMessage: $input.path('$.errorMessage');
}
```

This template translates the integration response body that contains the custom error JSON string to the following method response body. This method response body contains the custom error JSON object: 

```
{
    "errorMessage" : {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
};
```

 Depending on your API requirements, you may need to pass some or all of the custom error properties as method response header parameters. You can achieve this by applying the custom error mappings from the integration response body to the method response headers. 

For example, the following OpenAPI extension defines a mapping from the `errorMessage.errorType`, `errorMessage.httpStatus`, `errorMessage.trace.function`, and `errorMessage.trace` properties to the `error_type`, `error_status`, `error_trace_function`, and `error_trace` headers, respectively. 

```
"x-amazon-apigateway-integration": {
    "responses": {
        "default": {
          "statusCode": "200",
          "responseParameters": {
            "method.response.header.error_trace_function": "integration.response.body.errorMessage.trace.function",
            "method.response.header.error_status": "integration.response.body.errorMessage.httpStatus",
            "method.response.header.error_type": "integration.response.body.errorMessage.errorType",
            "method.response.header.error_trace": "integration.response.body.errorMessage.trace"
          },
          ...
        }
    }
}
```

 At runtime, API Gateway deserializes the `integration.response.body` parameter when performing header mappings. However, this deserialization applies only to body-to-header mappings for Lambda custom error responses and does not apply to body-to-body mappings using `$input.body`. With these custom-error-body-to-header mappings, the client receives the following headers as part of the method response, provided that the `error_status`, `error_trace`, `error_trace_function`, and `error_type` headers are declared in the method request. 

```
"error_status":"500",
"error_trace":"{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}",
"error_trace_function":"abc()",
"error_type":"InternalServerError"
```

The `errorMessage.trace` property of the integration response body is a complex property. It is mapped to the `error_trace` header as a JSON string. 

# HTTP integrations for REST APIs in API Gateway
HTTP integration

 You can integrate an API method with an HTTP endpoint using the HTTP proxy integration or the HTTP custom integration. 

API Gateway supports the following endpoint ports: 80, 443 and 1024-65535.

 With proxy integration, setup is simple. You only need to set the HTTP method and the HTTP endpoint URI, according to the backend requirements, if you are not concerned with content encoding or caching. 

 With custom integration, setup is more involved. In addition to the proxy integration setup steps, you need to specify how the incoming request data is mapped to the integration request and how the resulting integration response data is mapped to the method response. 

**Topics**
+ [

## Set up HTTP proxy integrations in API Gateway
](#api-gateway-set-up-http-proxy-integration-on-proxy-resource)
+ [

## Set up HTTP custom integrations in API Gateway
](#set-up-http-custom-integrations)

## Set up HTTP proxy integrations in API Gateway


To set up a proxy resource with the HTTP proxy integration type, create an API resource with a greedy path parameter (for example, `/parent/{proxy+}`) and integrate this resource with an HTTP backend endpoint (for example, `https://petstore-demo-endpoint.execute-api.com/petstore/{proxy}`) on the `ANY` method. The greedy path parameter must be at the end of the resource path. 

As with a non-proxy resource, you can set up a proxy resource with the HTTP proxy integration by using the API Gateway console, importing an OpenAPI definition file, or calling the API Gateway REST API directly. For detailed instructions about using the API Gateway console to configure a proxy resource with the HTTP integration, see [Tutorial: Create a REST API with an HTTP proxy integration](api-gateway-create-api-as-simple-proxy-for-http.md).

The following OpenAPI definition file shows an example of an API with a proxy resource that is integrated with the [PetStore](http://petstore-demo-endpoint.execute-api.com/petstore/pets) website.

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

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-09-12T23:19:28Z",
      "title": "PetStoreWithProxyResource"
   },
   "paths": {
      "/{proxy+}": {
         "x-amazon-apigateway-any-method": {
            "parameters": [
               {
                  "name": "proxy",
                  "in": "path",
                  "required": true,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {},
            "x-amazon-apigateway-integration": {
               "responses": {
                  "default": {
                     "statusCode": "200"
                  }
               },
               "requestParameters": {
                  "integration.request.path.proxy": "method.request.path.proxy"
               },
               "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/{proxy}",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "ANY",
               "cacheNamespace": "rbftud",
               "cacheKeyParameters": [
                  "method.request.path.proxy"
               ],
               "type": "http_proxy"
            }
         }
      }
   },
   "servers": [
      {
         "url": "https://4z9giyi2c1.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/test"
            }
         }
      }
   ]
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-09-12T23:19:28Z",
    "title": "PetStoreWithProxyResource"
  },
  "host": "4z9giyi2c1.execute-api.us-east-1.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {},
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.path.proxy": "method.request.path.proxy"
          },
          "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/{proxy}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "ANY",
          "cacheNamespace": "rbftud",
          "cacheKeyParameters": [
            "method.request.path.proxy"
          ],
          "type": "http_proxy"
        }
      }
    }
  }
}
```

------

In this example, a cache key is declared on the `method.request.path.proxy` path parameter of the proxy resource. This is the default setting when you create the API using the API Gateway console. The API's base path (`/test`, corresponding to a stage) is mapped to the website's PetStore page (`/petstore`). The single integration request mirrors the entire PetStore website using the API's greedy path variable and the catch-all `ANY` method. The following examples illustrate this mirroring. 
+ **Set `ANY` as `GET` and `{proxy+}` as `pets`**

  Method request initiated from the frontend:

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets HTTP/1.1
  ```

  Integration request sent to the backend:

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets HTTP/1.1
  ```

  The run-time instances of the `ANY` method and proxy resource are both valid. The call returns a `200 OK` response with the payload containing the first batch of pets, as returned from the backend.
+ **Set `ANY` as `GET` and `{proxy+}` as `pets?type=dog`**

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets?type=dog HTTP/1.1
  ```

  Integration request sent to the backend:

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets?type=dog HTTP/1.1
  ```

  The run-time instances of the `ANY` method and proxy resource are both valid. The call returns a `200 OK` response with the payload containing the first batch of specified dogs, as returned from the backend.
+ **Set `ANY` as `GET` and `{proxy+}` as `pets/{petId}`**

  Method request initiated from the frontend:

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets/1 HTTP/1.1
  ```

  Integration request sent to the backend:

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets/1 HTTP/1.1
  ```

  The run-time instances of the `ANY` method and proxy resource are both valid. The call returns a `200 OK` response with the payload containing the specified pet, as returned from the backend.
+ **Set `ANY` as `POST` and `{proxy+}` as `pets`**

  Method request initiated from the frontend:

  ```
  POST https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets HTTP/1.1
  Content-Type: application/json
  Content-Length: ...
  
  {
    "type" : "dog",
    "price" : 1001.00
  }
  ```

  Integration request sent to the backend:

  ```
  POST http://petstore-demo-endpoint.execute-api.com/petstore/pets HTTP/1.1
  Content-Type: application/json
  Content-Length: ...
  
  {
    "type" : "dog",
    "price" : 1001.00
  }
  ```

  The run-time instances of the `ANY` method and proxy resource are both valid. The call returns a `200 OK` response with the payload containing the newly created pet, as returned from the backend.
+ **Set `ANY` as `GET` and `{proxy+}` as `pets/cat`**

  Method request initiated from the frontend:

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets/cat
  ```

  Integration request sent to the backend:

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets/cat
  ```

  The run-time instance of the proxy resource path does not correspond to a backend endpoint and the resulting request is invalid. As a result, a `400 Bad Request` response is returned with the following error message. 

  ```
  {
    "errors": [
      {
        "key": "Pet2.type",
        "message": "Missing required field"
      },
      {
        "key": "Pet2.price",
        "message": "Missing required field"
      }
    ]
  }
  ```
+ **Set `ANY` as `GET` and `{proxy+}` as `null`**

  Method request initiated from the frontend:

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test
  ```

  Integration request sent to the backend:

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets
  ```

  The targeted resource is the parent of the proxy resource, but the run-time instance of the `ANY` method is not defined in the API on that resource. As a result, this `GET` request returns a `403 Forbidden` response with the `Missing Authentication Token` error message as returned by API Gateway. If the API exposes the `ANY` or `GET` method on the parent resource (`/`), the call returns a `404 Not Found` response with the `Cannot GET /petstore` message as returned from the backend.

For any client request, if the targeted endpoint URL is invalid or the HTTP verb is valid but not supported, the backend returns a `404 Not Found` response. For an unsupported HTTP method, a `403 Forbidden` response is returned.

## Set up HTTP custom integrations in API Gateway
Set up HTTP custom integrations

 With the HTTP custom integration, also known as the non-proxy integration, you have more control of which data to pass between an API method and an API integration and how to pass the data. You do this using data mappings. 

As part of the method request setup, you set the [requestParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html#requestParameters) property on a [Method](https://docs.amazonaws.cn/apigateway/latest/api/API_Method.html) resource. This declares which method request parameters, which are provisioned from the client, are to be mapped to integration request parameters or applicable body properties before being dispatched to the backend. Then, as part of the integration request setup, you set the [requestParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html#requestParameters) property on the corresponding [Integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource to specify the parameter-to-parameter mappings. You also set the [requestTemplates](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html#requestTemplates) property to specify mapping templates, one for each supported content type. The mapping templates map method request parameters, or body, to the integration request body. 

 Similarly, as part of the method response setup, you set the [responseParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html#responseParameters) property on the [MethodResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_MethodResponse.html) resource. This declares which method response parameters, to be dispatched to the client, are to be mapped from integration response parameters or certain applicable body properties that were returned from the backend. You then set up the [selectionPattern](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern) to choose an integration response based on the response from the backend. For a non-proxy HTTP integration, this is a regular expression. For example, to map all 2xx HTTP response status codes from an HTTP endpoint to this output mapping, use `2\d{2}`.

**Note**  
API Gateway uses Java pattern-style regexes for response mapping. For more information, see [Pattern](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) in the Oracle documentation.

Then, as part of the integration response setup, you set the [responseParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html#responseParameters) property on the corresponding [IntegrationResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resource to specify the parameter-to-parameter mappings. You also set the [responseTemplates](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html#responseTemplates) map to specify mapping templates, one for each supported content type. The mapping templates map integration response parameters, or integration response body properties, to the method response body. 

 For more information about setting up mapping templates, see [Data transformations for REST APIs in API Gateway](rest-api-data-transformations.md).

# Stream the integration response for your proxy integrations in API Gateway
Stream the integration response for your proxy integrations

You can configure your proxy integration to control how API Gateway returns your integration response. By default, API Gateway waits to receive the complete response before beginning transmission. However, if you set your integration's response transfer mode to `STREAM`, API Gateway doesn't wait for a response to be completely computed before sending it to the client. Response streaming works for all REST API endpoint types.

Use response streaming for the following use cases:
+ Lower the time-to-first-byte (TTFB) for generative AI applications like chatbots.
+ Stream large image, video, or music files without using an S3 pre-signed URL.
+ Perform long-running operations while reporting incremental progress like server-sent events (SSE).
+ Exceed API Gateway's 10 MB response payload limit.
+ Exceed API Gateway's 29 second timeout limit without requesting an integration timeout limit increase.
+ Receive a binary payload without configuring the binary media types.

## Considerations for response payload streaming


The following considerations might impact your use of response payload streaming:
+ You can only use response payload streaming for `HTTP_PROXY` or `AWS_PROXY` integration types. This includes Lambda proxy integrations and private integrations that use `HTTP_PROXY` integrations.
+ The default transfer mode setting is `BUFFERED`. To use response streaming you must change the response transfer mode to `STREAM`.
+ Response streaming is only supported for REST APIs.
+ Request streaming isn't supported.
+ You can stream your response for up to 15 minutes.
+ Your streams are subject to idle timeouts. For Regional or private endpoints, the timeout is 5 minutes. For edge-optimized endpoints, the timeout is 30 seconds.
+ If you use response streaming for a Regional REST API with your own CloudFront distribution, you can achieve an idle time out greater than 30 seconds by increasing the response timeout of your CloudFront distribution. For more information, see [Response timeout](https://docs.amazonaws.cn/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesOrigin.html#DownloadDistValuesOriginResponseTimeout).
+ When the response transfer mode is set to `STREAM`, API Gateway can’t support features that require buffering the entire integration response. Because of this, the following features aren't supported with response streaming:
  + Endpoint caching
  + Content encoding. If you want to compress your integration response, do this in your integration.
  + Response transformation with VTL
+ Within each streaming response, the first 10MB of response payload is not subject to any bandwidth restrictions. Response payload data exceeding 10MB is restricted to 2MB/s.
+ When the connection between the client and API Gateway or between API Gateway and Lambda is closed due to timeout, the Lambda function might continue to execute. For more information, see [Configure Lambda function timeout](https://docs.amazonaws.cn/lambda/latest/dg/configuration-timeout.html).
+ Response streaming incurs a cost. For more information, see [API Gateway Pricing](https://www.amazonaws.cn/api-gateway/pricing/).

# Set up an HTTP proxy integration with payload response streaming in API Gateway
Set up an HTTP proxy integration with payload response streaming

When you set up response payload streaming, you specify the response transfer mode in the integration request of your method. You configure these settings in the integration request to control how API Gateway behaves before and during the integration response. When you use response streaming, you can configure the integration timeout up to 15 minutes.

When you use payload response streaming with an `HTTP_PROXY` integration, API Gateway won't send the HTTP response status code or any HTTP response headers until it fully receives all headers.

## Create an HTTP proxy integration with payload response streaming


The following procedure shows you how to import a new API with the `responseTransferMode` set to `STREAM`. If you have an existing integration API and want to modify the `responseTransferMode`, see [Update the response transfer mode for an HTTP proxy integration](#response-streaming-http-update).

------
#### [ Amazon Web Services Management Console ]

**To create an HTTP proxy integration with payload response streaming**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose **Create resource**.

1. For **Resource name**, enter **streaming**.

1. Choose **Create resource**.

1. With the **/streaming** resource selected, choose **Create method**.

1. For **Method type**, choose **ANY**.

1. For **Integration type**, choose **HTTP**.

1. Choose **HTTP proxy integration**.

1. For **Response transfer mode**, choose **Stream**.

1. For **HTTP method**, choose a method.

1. For **Endpoint URL**, enter an integration endpoint. Make sure that you choose an endpoint that produces a large payload to be streamed back to you.

1. Choose **Create method**.

After you create your method, deploy your API.

**To deploy your API**

1. Choose **Deploy API**.

1. For **Stage**, select **New stage**.

1. For **Stage name**, enter **prod**.

1. (Optional) For **Description**, enter a description.

1. Choose **Deploy**.

------
#### [ Amazon CLI ]

**To create a new API with payload response streaming**

1. Copy the following Open API file, and then save it as `ResponseStreamDemoSwagger.yaml`. In this file, `responseTransferMode` is set to `STREAM`. The integration endpoint is set to `https://example.com`, but we recommend that you modify it to an endpoint that produces a large payload to be streamed back to you.

   ```
   openapi: "3.0.1"
   info:
     title: "ResponseStreamingDemo"
     version: "2025-04-28T17:28:25Z"
   servers:
   - url: "{basePath}"
     variables:
       basePath:
         default: "prod"
   paths:
     /streaming:
       get:
         x-amazon-apigateway-integration:
           httpMethod: "GET"
           uri: "https://example.com"
           type: "http_proxy"
           timeoutInMillis: 900000
           responseTransferMode: "STREAM"
   ```

1. Use the following `import-rest-api` command to import your OpenAPI definition:

   ```
   aws apigateway import-rest-api \
     --body 'fileb://~/ResponseStreamDemoSwagger.yaml' \
     --parameters endpointConfigurationTypes=REGIONAL \
     --region us-west-1
   ```

1. Use the following `create-deployment` command to deploy your new API to a stage:

   ```
   aws apigateway create-deployment \
     --rest-api-id a1b2c3 \
     --stage-name prod \
     --region us-west-1
   ```

------

## Update the response transfer mode for an HTTP proxy integration


The following procedure shows how to update the response transfer mode for an HTTP proxy integration.

------
#### [ Amazon Web Services Management Console ]

**To update the response transfer mode for an HTTP proxy integration**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose a method.

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

1. For **Response transfer mode**, choose **Stream**.

1. Choose **Save**.

After you update your method, deploy your API.

**To deploy your API**

1. Choose **Deploy API**.

1. For **Stage**, select **New stage**.

1. For **Stage name**, enter **prod**.

1. (Optional) For **Description**, enter a description.

1. Choose **Deploy**.

------
#### [ Amazon CLI ]

The following `update-integration` command updates the transfer mode of an integration from `BUFFERED` to `STREAM`. For any existing APIs, the response transfer mode for all integrations is set to `BUFFERED`.

```
aws apigateway update-integration \
 --rest-api-id a1b2c3 \
 --resource-id aaa111 \
 --http-method GET \
 --patch-operations "op='replace',path='/responseTransferMode',value=STREAM" \
 --region us-west-1
```

You need to redeploy your API for the changes to take effect. If you customized the integration timeout, this timeout value is removed, as API Gateway streams your response for up to 5 minutes.

The following `update-integration` command updates the transfer mode of an integration from `STREAM` to `BUFFERED`:

```
aws apigateway update-integration \
 --rest-api-id a1b2c3 \
 --resource-id aaa111 \
 --http-method GET \
 --patch-operations "op='replace',path='/responseTransferMode',value=BUFFERED" \
 --region us-west-1
```

You need to redeploy your API for the changes to take effect.

------

# Set up a Lambda proxy integration with payload response streaming in API Gateway
Set up a Lambda proxy integration with payload response streaming

You can stream the response of a Lambda function to improve time to first byte (TTFB) performance and send partial responses back to the client as they become available. API Gateway requires you to use the [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html) Lambda API to invoke your Lambda function. API Gateway passes an event object to the Lambda function. The backend Lambda function parses the incoming request data to determine the response that it returns. In order for API Gateway to stream the Lambda output, the Lambda function must output the [format](#response-transfer-mode-lambda-format) required by API Gateway.

## Differences in Lambda proxy integrations between stream and buffered response transfer mode


The following list describes the differences between a Lambda proxy integration and a Lambda proxy integration for response streaming:
+ API Gateway uses the [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html) API to invoke the Lambda proxy integration for response streaming. This results in a different URI, which is the following:

  ```
  arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations
  ```

  This ARN uses a different date for the API version and a different service action compared to Lambda proxy integration.

  If you use the API Gateway console for response streaming, the console uses the correct URI for you.
+ In a Lambda proxy integration, API Gateway sends the response to client only after it receives the full response from Lambda. In a Lambda proxy integration for response streaming, API Gateway begins the payload stream after it receives the valid metadata and delimiter from Lambda. 
+ Lambda proxy integration for response streaming uses the same input format as the proxy integration, but it requires a different output format.

## Lambda proxy integration format for response streaming


When API Gateway invokes a Lambda function with response streaming, the input format is the same as the input format of a Lambda function for proxy integration. For more information, see [Input format of a Lambda function for proxy integration](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format). 

When Lambda streams a response to API Gateway, the response must adhere to the following format. This format uses a delimiter to separate the metadata JSON and the raw payload. In this case, the payload data is streamed as it is transmitted by your streaming Lambda function:

```
{
  "headers": {"headerName": "headerValue", ...},
  "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
  "cookies" : ["cookie1", "cookie2"],
  "statusCode": httpStatusCode
}<DELIMITER>PAYLOAD1 | PAYLOAD2 | PAYLOAD3
```

In the output:
+ The `headers`, `multiValueHeaders`, `cookies`, and `statusCode` keys can be unspecified if no extra response headers are to be returned.
+ The `headers` key can only contain single-value headers.
+ The output expects the headers to contain either `Transfer-Encoding: chunked` or `Content-length: number`. If your function doesn't return either of these headers, API Gateway appends `Transfer-Encoding: chunked` to the response header.
+ The `multiValueHeaders` key can contain multi-value headers as well as single-value headers. You can use the `multiValueHeaders` key to specify all of your extra headers, including any single-value ones.
+ If you specify values for both `headers` and `multiValueHeaders`, API Gateway merges them into a single list. If the same key-value pair is specified in both, only the values from `multiValueHeaders` will appear in the merged list.
+ The metadata must be valid JSON. Only `headers`, `multiValueHeaders`, `cookies` and the `statusCode` keys are supported.
+ You must provide a delimiter after the metadata JSON. The delimiter must be 8 null bytes and it must appear within the first 16KB of stream data.
+ API Gateway doesn't require a specific format for the method response payload.

If you're using a function URL to stream your Lambda function, you must modify the input and the output of your Lambda function to satisfy these requirements.

If your Lambda function output doesn't adhere to the requirements of this format, API Gateway might still invoke your Lambda function. The following table shows the combinations of API integration request settings and Lambda function code that is supported by API Gateway. This includes supported combinations for response transfer mode of buffered.


| Response transfer mode | Function code adheres to the required format | Lambda invoke API | Supported by API Gateway | 
| --- | --- | --- | --- | 
|  Stream  |  Yes  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  Yes. API Gateway streams your response.  | 
|  Stream  |  No  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  No. API Gateway invokes your Lambda function and return a 500 error response.  | 
|  Stream  |  Yes  |   [Invoke](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Stream  |  No  |   [Invoke](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Buffered  |  Yes  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Buffered  |  No  |   [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Buffered  |  Yes  |   [Invoke](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  API Gateway returns the HTTP headers and status code but not the response body.  | 
|  Buffered  |  No  |   [Invoke](https://docs.amazonaws.cn/lambda/latest/api/API_Invoke.html)  |  Yes. This is a Lambda proxy integration. For more information, see [Lambda proxy integration](set-up-lambda-proxy-integrations.md).  | 

# Configure a Lambda proxy integration with payload response streaming in API Gateway
Configure a Lambda proxy integration with payload response streaming

When you set up response payload streaming, you specify the transfer mode in the integration request of your resource. You configure these settings in the integration request to control how API Gateway behaves before and during the integration response.

## Example Lambda functions for response streaming


Your Lambda function must adhere to the [Lambda proxy integration format for response streaming](response-transfer-mode-lambda.md#response-transfer-mode-lambda-format). We recommend you use one of the three example Lambda functions to test out response streaming. When you create your Lambda function, make sure to do the following:
+ Provide an adequate timeout for your function. We recommend you configure a timeout of at least 1 minute to learn about response streaming. When you create your production resources, make sure your Lambda function timeout covers the full request cycle. For more information, see [Configure Lambda function timeout](https://docs.amazonaws.cn/lambda/latest/dg/configuration-timeout.html).
+ Use the latest Node.js runtime.
+ Use a Region where Lambda response streaming is available.

------
#### [ Using HttpResponseStream.from ]

The following code example streams the JSON metadata objects and payloads back to the client using the `awslambda.HttpResponseStream()` method without using the pipeline method. You don't need to create the delimiter. For more information, see [Writing response streaming-enabled Lambda functions](https://docs.amazonaws.cn/lambda/latest/dg/config-rs-write-functions.html).

```
export const handler = awslambda.streamifyResponse(
  async (event, responseStream, context) => {
    const httpResponseMetadata = {
      "statusCode": 200,
      "headers": {
        "x-foo": "bar"
      },
      "multiValueHeaders": {
        "x-mv1": ["hello", "world"],
        "Set-Cookie": ["c1=blue", "c2=red"]
      }
    };

    responseStream = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata);
    await new Promise(r => setTimeout(r, 1000)); // synthetic delay

    responseStream.write("First payload ");
    await new Promise(r => setTimeout(r, 1000)); // synthetic delay

    responseStream.write("Final payload");
    responseStream.end();
});
```

------
#### [ Using the pipeline method ]

Lambda recommends that when you write response streaming-enabled functions, you use the `awslambda.streamifyResponse()` decorator that the native Node.js runtimes provide, and the `pipeline()` method. When you use the pipeline method, you don't need to create the delimiter, Lambda does this for you. For more information, see [Writing response streaming-enabled Lambda functions](https://docs.amazonaws.cn/lambda/latest/dg/config-rs-write-functions.html).

The following code example streams the JSON metadata objects and three payloads back to the client.

```
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';

export const handler = awslambda.streamifyResponse(
  async (event, responseStream, context) => {
    const httpResponseMetadata = {
      statusCode: 200,
      headers: {
        "Content-Type": "text/plain",
        "X-Custom-Header": "Example-Custom-Header"
      }
    };

    responseStream = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata);

    const dataStream = Readable.from(async function* () {
      yield "FIRST payload\n";
      await new Promise(r => setTimeout(r, 1000));
      yield "SECOND payload\n";
      await new Promise(r => setTimeout(r, 1000));
      yield "THIRD payload\n";
      await new Promise(r => setTimeout(r, 1000));
    }());

    await pipeline(dataStream, responseStream);
  }
);
```

------
#### [ Without using the pipeline method ]

The following code example streams the JSON metadata objects and three payloads back to the client without using the `awslambda.HttpResponseStream()` method. Without the `awslambda.HttpResponseStream()` method, you must include a delimiter of 8 null bytes between the metadata and the payload. 

```
export const handler = awslambda.streamifyResponse(async (event, response, ctx) => {
  response.write('{"statusCode": 200, "headers": {"hdr-x": "val-x"}}');
  response.write("\x00".repeat(8)); // DELIMITER
  await new Promise(r => setTimeout(r, 1000));

  response.write("FIRST payload");
  await new Promise(r => setTimeout(r, 1000));

  response.write("SECOND payload");
  await new Promise(r => setTimeout(r, 1000));

  response.write("FINAL payload");
  response.end();
});
```

------

## Create a Lambda proxy integration with payload response streaming


The following procedure shows how to create a Lambda proxy integration with payload response streaming. Use the example Lambda function or create your own.

------
#### [ Amazon Web Services Management Console ]

**To create a Lambda proxy integration with payload response streaming**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose **Create resource**.

1. For **Resource name**, enter **streaming**.

1. Choose **Create resource**.

1. With the **/streaming** resource selected, choose **Create method**.

1. For **Method type**, choose **ANY**.

1. For **Integration type**, choose **Lambda**.

1. Choose **Lambda proxy integration**.

1. For **Response transfer mode**, choose **Stream**.

1. For **Lambda function**, choose the name of your Lambda function.

   The API Gateway console automatically uses [InvokeWithResponseStream](https://docs.amazonaws.cn/lambda/latest/api/API_InvokeWithResponseStream.html) API to invoke the Lambda function. You are responsible for writing a response streaming-enabled Lambda function. For an example, see [Example Lambda functions for response streaming](#response-streaming-lambda-example).

1. Choose **Create method**.

After you create your method, deploy your API.

**To deploy your API**

1. Choose **Deploy API**.

1. For **Stage**, select **New stage**.

1. For **Stage name**, enter **prod**.

1. (Optional) For **Description**, enter a description.

1. Choose **Deploy**.

------
#### [ Amazon CLI ]

The following procedure shows you how to import a new API with the `responseTransferMode` set to `STREAM`. If you have an existing integration API and want to modify the `responseTransferMode`, see [Update the response transfer mode for a Lambda proxy integration](#response-streaming-lambda-update).

**To create a new API with payload response streaming**

1. Copy the following Open API file, and then save it as `ResponseStreamDemoSwagger.yaml`. In this file, `responseTransferMode` is set to `STREAM`, and the integration URI is set to `arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations`.

   Replace the function name from `my-function` with a streaming-enabled function and replace the credentials with an IAM role that has policies allowing the `apigateway` service to invoke Lambda functions.

   ```
   openapi: "3.0.1"
   info:
     title: "ResponseStreamingDemo"
     version: "2025-04-28T17:28:25Z"
   servers:
   - url: "{basePath}"
     variables:
       basePath:
         default: "prod"
   paths:
     /lambda:
       get:
         x-amazon-apigateway-integration:
           httpMethod: "POST"
           uri: "arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations"
           type: "aws_proxy"
           timeoutInMillis: 90000
           responseTransferMode: "STREAM"
           credentials: "arn:aws:iam::111122223333:role/apigateway-lambda-role"
   ```

   Instead of supplying an IAM role for credentials, you can use the `add-permission` command for Lambda to add resource-based permissions.

1. Use the following `import-rest-api` command to import your OpenAPI definition:

   ```
   aws apigateway import-rest-api \
     --body 'fileb://~/ResponseStreamDemoSwagger.yaml' \
     --parameters endpointConfigurationTypes=REGIONAL \
     --region us-west-1
   ```

1. Use the following `create-deployment` command to deploy your new API to a stage:

   ```
   aws apigateway create-deployment \
     --rest-api-id a1b2c2 \
     --stage-name prod \
     --region us-west-1
   ```

------

### Update the response transfer mode for a Lambda proxy integration


The following procedure shows how to update the response transfer mode for a Lambda proxy integration. When you change the response transfer mode to streaming, update your Lambda function so it adheres to the requirements for response streaming. Use the example Lambda function or create your own.

------
#### [ Amazon Web Services Management Console ]

**To update the response transfer mode for a Lambda proxy integration**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose a method.

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

1. For **Response transfer mode**, choose **Stream**.

1. For **Lambda function**, choose the name of your Lambda function.

1. Choose **Save**.

After you update your method, deploy your API.

**To deploy your API**

1. Choose **Deploy API**.

1. For **Stage**, select **New stage**.

1. For **Stage name**, enter **prod**.

1. (Optional) For **Description**, enter a description.

1. Choose **Deploy**.

------
#### [ Amazon CLI ]

1. Update your Lambda function to be streaming-enabled.

1. Use the following Amazon CLI command to update the integration URI and response transfer mode of your integration:

   ```
   aws apigateway update-integration \
    --rest-api-id a1b2c3 \
    --resource-id aaa111 \
    --http-method ANY \
    --patch-operations "[{\"op\":\"replace\",\"path\":\"/uri\",\"value\":\"arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations\"}, {\"op\":\"replace\",\"path\":\"/responseTransferMode\",\"value\":\"STREAM\"}]" \
    --region us-west-1
   ```

1. Redeploy your API for the changes to take effect.

------

# Troubleshoot issues with response streaming in API Gateway
Troubleshoot issues with response streaming

The following troubleshooting guidance might help resolve issues with your APIs that use response streaming.

## General troubleshooting


You can use the [TestInvokeMethod](https://docs.amazonaws.cn/apigateway/latest/api/API_TestInvokeMethod.html) or the console's test tab to test your stream response. The following considerations might impact your use of test invoke for response streaming:
+ When you test your method, API Gateway buffers your streamed response payload. Once any of the following conditions have been met, API Gateway returns a one-time response containing the buffered payload:
  + The request is complete
  + 35 seconds have elapsed
  + More than 1 MB of response payload has been buffered
+ If more than 35 seconds elapse before your method returns an HTTP response status and all headers, then the response status returned in TestInvokeMethod is 0.
+ API Gateway doesn't produce any execution logs.

After you've deployed your API, you can test your stream response by using a curl command. We recommend that you use the `-i` option to include protocol response headers in the output. To see the response data as it arrives, use the curl option `--no-buffer`

## Troubleshoot cURL errors


If you're testing an integration and you receive the error `curl: (18) transfer closed with outstanding read data remaining`, make sure the timeout of your integration is long enough. If you're using a Lambda function, you need to update the response timeout of the Lambda function. For more information, see [Configure Lambda function timeout](https://docs.amazonaws.cn/lambda/latest/dg/configuration-timeout.html).

## Troubleshoot using access logging


You can use access logs for your REST API stage to log and troubleshoot your response stream. In addition to the existing variables, you can use the following access log variables:

`$context.integration.responseTransferMode`  
The response transfer mode of your integration. This can be either `BUFFERED` or `STREAMED`.

`$context.integration.timeToAllHeaders`  
The time between when API Gateway establishes the integration connection to when it receives all integration response headers from the client.

`$context.integration.timeToFirstContent`  
The time between when API Gateway establishes the integration connection to when it receives the first content bytes.

`$context.integration.latency` or `$context.integrationLatency`  
The time when API Gateway establishes the integration connection to when the integration response stream is complete.

The following figure shows how these access log variables represent different components of a response stream.

For more information about access logs, see [Set up CloudWatch logging for REST APIs in API Gateway](set-up-logging.md). You can also use X-Ray to monitor your response stream. For more information, see [Trace user requests to REST APIs using X-Ray in API Gateway](apigateway-xray.md).

# Private integrations for REST APIs in API Gateway
Private integration

Use a private integration to expose your HTTP/HTTPS resources within an Amazon VPC for access by clients outside of the VPC. This extends access to your private VPC resources beyond the VPC boundaries. You can control access to your API by using any of the [authorization methods](apigateway-control-access-to-api.md) that API Gateway supports.

To create a private integration, you must first create a VPC link. API Gateway supports VPC links V2 for REST APIs. VPC links V2 let you create private integrations that connect your REST API to Application Load Balancers without using an Network Load Balancer. Using an Application Load Balancer allows you to connect to Amazon ECSs container-based applications and many other backends. VPC links V1 are considered a legacy integration type. While they are supported by API Gateway, we recommend that you don't create new VPC links V1.

## Considerations


The following considerations might impact your use of private integrations:
+ All resources must be owned by the same Amazon Web Services account. This includes the load balancer, VPC link and REST API.
+ By default, private integration traffic uses the HTTP protocol. To use HTTPS, specify an [https://docs.amazonaws.cn/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri](https://docs.amazonaws.cn/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri) that contains a secure server name, such as `https://example.com:443/test`.
+ In a private integration, API Gateway includes the [stage](set-up-stages.md) portion of the API endpoint in the request to your backend resources. For example, if you request the `test` stage of an API, API Gateway includes `test/path` in the request to your private integration. To remove the stage name from the request to your backend resources, use [parameter mapping](rest-api-parameter-mapping.md) to create an override for the `$context.requestOverride.path` variable.
+ Private integrations with Amazon Cloud Map aren't supported.

**Topics**
+ [

## Considerations
](#private-integrations-considerations)
+ [

# Set up VPC links V2 in API Gateway
](apigateway-vpc-links-v2.md)
+ [

# Set up a private integration
](set-up-private-integration.md)
+ [

# Private integration using VPC links V1 (legacy)
](vpc-links-v1.md)

# Set up VPC links V2 in API Gateway
VPC links V2

VPC links enable you to create private integrations that connect your API routes to private resources in a VPC, such as Application Load Balancers or Amazon ECS container-based applications. A private integration uses a VPC link V2 to encapsulate connections between API Gateway and targeted VPC resources. You can reuse VPC links across different resources and APIs.

When you create a VPC link, API Gateway creates and manages [elastic network interfaces](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/using-eni.html) for the VPC link V2 in your account. This process can take a few minutes. When a VPC link V2 is ready to use, its state transitions from `PENDING` to `AVAILABLE`. 

**Note**  
If no traffic is sent over the VPC link for 60 days, it becomes `INACTIVE`. When a VPC link is in an `INACTIVE` state, API Gateway deletes all of the VPC link’s network interfaces. This causes API requests that depend on the VPC link to fail. If API requests resume, API Gateway reprovisions network interfaces. It can take a few minutes to create the network interfaces and reactivate the VPC link. You can use the VPC link status to monitor the state of your VPC link.

## Create a VPC link V2 by using the Amazon CLI


To create a VPC link V2, all resources involved must be owned by the same Amazon account. The following [create-vpc-link](https://docs.amazonaws.cn/cli/latest/reference/apigatewayv2/create-vpc-link.html) command creates a VPC link:

```
aws apigatewayv2 create-vpc-link --name MyVpcLink \
    --subnet-ids subnet-aaaa subnet-bbbb \
    --security-group-ids sg1234 sg5678
```

**Note**  
VPC links V2 are immutable. After you create a VPC link V2, you can’t change its subnets or security groups.

## Delete a VPC link V2 by using the Amazon CLI


The following [delete-vpc-link](https://docs.amazonaws.cn/cli/latest/reference/apigatewayv2/delete-vpc-link.html) command deletes a VPC link.

```
aws apigatewayv2 delete-vpc-link --vpc-link-id abcd123
```

## Availability by Region


VPC links V2 are supported in the following Regions and Availability Zones:

[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/apigateway-vpc-links-v2.html)

# Set up a private integration


To create a private integration with an Application Load Balancer or Network Load Balancer, you create an HTTP proxy integration, specify the [VPC link V2](apigateway-vpc-links-v2.md) to use, and provide the ARN of an Network Load Balancer or an Application Load Balancer. By default, private integration traffic uses the HTTP protocol. To use HTTPS, specify an [https://docs.amazonaws.cn/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri](https://docs.amazonaws.cn/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri) that contains a secure server name, such as `https://example.com:443/test`. For a complete tutorial on how to create a REST API with a private integration, see [Tutorial: Create a REST API with a private integration](getting-started-with-private-integration.md).

## Create a private integration


The following procedure shows how to create a private integration that connects to a load balancer by using a VPC link V2.

------
#### [ Amazon Web Services Management Console ]

For a tutorial on how to create a private integration see, [Tutorial: Create a REST API with a private integration](getting-started-with-private-integration.md).

------
#### [ Amazon CLI ]

The following [put-integration](https://docs.amazonaws.cn/cli/latest/reference/latest/api/API_PutIntegration.html) command creates a private integration that connects to a load balancer by using a VPC link V2:

```
aws apigateway put-integration \
    --rest-api-id abcdef123 \
    --resource-id aaa000 \
    --integration-target 'arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011' \
    --uri 'https://example.com:443/path' \
    --http-method GET \
    --type HTTP_PROXY \
    --integration-http-method GET \
    --connection-type VPC_LINK \
    --connection-id bbb111
```

Instead of directly providing the connection ID, you can use a stage variable instead. When you deploy your API to a stage, you set the VPC link V2 ID. The following [put-integration](https://docs.amazonaws.cn/cli/latest/reference/latest/api/API_PutIntegration.html) command creates a private integration using a stage variable for the VPC link V2 ID:

```
aws apigateway put-integration \
    --rest-api-id abcdef123 \
    --resource-id aaa000 \
    --integration-target 'arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011' \
    --uri 'https://example.com:443/path' \
    --http-method GET \
    --type HTTP_PROXY \
    --integration-http-method GET \
    --connection-type VPC_LINK \
    --connection-id "\${stageVariables.vpcLinkV2Id}"
```

Make sure to double-quote the stage variable expression (\$1\$1stageVariables.vpcLinkV2Id\$1) and escape the \$1 character.

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

You can set up an API with the private integration by importing the API's OpenAPI file. The settings are similar to the OpenAPI definitions of an API with HTTP integrations, with the following exceptions: 
+ You must explicitly set `connectionType` to `VPC_LINK`.
+ You must explicitly set `connectionId` to the ID of a `VpcLinkV2` or to a stage variable referencing the ID of a `VpcLinkV2`.
+ The `uri` parameter in the private integration points to an HTTP/HTTPS endpoint in the VPC, but is used instead to set up the integration request's `Host` header.
+ The `uri` parameter in the private integration with an HTTPS endpoint in the VPC is used to verify the stated domain name against the one in the certificate installed on the VPC endpoint.

 You can use a stage variable to reference the `VpcLinkV2` ID. Or you can assign the ID value directly to `connectionId`. 

The following JSON-formatted OpenAPI file shows an example of an API with a VPC link as referenced by a stage variable (`${stageVariables.vpcLinkIdV2}`):

```
{
  "swagger": "2.0",
  "info": {
    "version": "2017-11-17T04:40:23Z",
    "title": "MyApiWithVpcLinkV2"
  },
  "host": "abcdef123.execute-api.us-west-2.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/": {
      "get": {
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "https://example.com:443/path",
          "passthroughBehavior": "when_no_match",
          "connectionType": "VPC_LINK",
          "connectionId": "${stageVariables.vpcLinkV2Id}",
          "integration-target": "arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011",
          "httpMethod": "GET",
          "type": "http_proxy"
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------

## Update a private integration


The following example updates the VPC link V2 for a private integration.

------
#### [ Amazon Web Services Management Console ]

**To update a private integration**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API with a private integration.

1. Choose the resource and method that uses a private integration.

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

1. You can edit the setting of your private integration. If you are currently using a VPC link V1, you can change your VPC link to a VPC link V2.

1. Choose **Save**.

1. Redeploy your API for the changes to take effect.

------
#### [ Amazon CLI ]

The following [update-integration](https://docs.amazonaws.cn/cli/latest/reference/latest/api/API_PutIntegration.html) command updates a private integration to use a VPC link V2:

```
aws apigateway update-integration \
    --rest-api-id a1b2c3d4e5 \
    --resource-id a1b2c3 \
    --http-method GET \
    --patch-operations "[{\"op\":\"replace\",\"path\":\"/connectionId\",\"value\":\"pk0000\"}, {\"op\":\"replace\",\"path\":\"/uri\",\"value\":\"http://example.com\"}, {\"op\":\"replace\",\"path\":\"/integrationTarget\",\"value\":\"arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011\"}]"
```

------

# Private integration using VPC links V1 (legacy)


**Note**  
The following implementation of private integrations uses VPC links V1. VPC links V1 are legacy resources. We recommend that you use [VPC links V2 for REST APIs](apigateway-vpc-links-v2.md).

To create a private integration, you must first create a Network Load Balancer. Your Network Load Balancer must have a [listener](https://docs.amazonaws.cn/elasticloadbalancing/latest/network/load-balancer-listeners.html) that routes requests to resources in your VPC. To improve the availability of your API, ensure that your Network Load Balancer routes traffic to resources in more than one Availability Zone in the Amazon Web Services Region. Then, you create a VPC link that you use to connect your API and your Network Load Balancer. After you create a VPC link, you create private integrations to route traffic from your API to resources in your VPC through your VPC link and Network Load Balancer. The Network Load Balancer and API must be owned by the same Amazon Web Services account.

**Topics**
+ [

# Set up a Network Load Balancer for API Gateway private integrations (legacy)
](set-up-nlb-for-vpclink-using-console.md)
+ [

# Grant permissions for API Gateway to create a VPC link (legacy)
](grant-permissions-to-create-vpclink.md)
+ [

# Set up an API Gateway API with private integrations using the Amazon CLI (legacy)
](set-up-api-with-vpclink-cli.md)
+ [

# API Gateway accounts used for private integrations (legacy)
](set-up-api-with-vpclink-accounts.md)

# Set up a Network Load Balancer for API Gateway private integrations (legacy)
Set up a Network Load Balancer for private integrations (legacy)

**Note**  
The following implementation of private integrations uses VPC links V1. VPC links V1 are legacy resources. We recommend that you use [VPC links V2 for REST APIs](apigateway-vpc-links-v2.md).

 The following procedure outlines the steps to set up a Network Load Balancer (NLB) for API Gateway private integrations using the Amazon EC2 console and provides references for detailed instructions for each step. 

For each VPC you have resources in, you only need to configure one NLB and one VPCLink. The NLB supports multiple [listeners](https://docs.amazonaws.cn/elasticloadbalancing/latest/network/load-balancer-listeners.html) and [target groups](https://docs.amazonaws.cn/elasticloadbalancing/latest/network/load-balancer-target-groups.html) per NLB. You can configure each service as a specific listener on the NLB and use a single VPCLink to connect to the NLB. When creating the private integration in API Gateway you then define each service using the specific port that is assigned for each service. For more information, see [Tutorial: Create a REST API with a private integration](getting-started-with-private-integration.md). The Network Load Balancer and API must be owned by the same Amazon Web Services account.

**To create a Network Load Balancer for private integration using the API Gateway console**

1. Sign in to the Amazon Web Services Management Console and open the Amazon EC2 console at [https://console.amazonaws.cn/ec2/](https://console.amazonaws.cn/ec2/).

1. Set up a web server on an Amazon EC2 instance. For an example setup, see [Installing a LAMP Web Server on Amazon Linux 2](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html). 

1. Create a Network Load Balancer, register the EC2 instance with a target group, and add the target group to a listener of the Network Load Balancer. For details, follow the instructions in [Getting Started with Network Load Balancers](https://docs.amazonaws.cn/elasticloadbalancing/latest/network/network-load-balancer-getting-started.html). 

1. After the Network Load Balancer is created, do the following:

   1.  Note the ARN of the Network Load Balancer. You will need it to create a VPC link in API Gateway for integrating the API with the VPC resources behind the Network Load Balancer.

   1.  Turn off security group evaluation for PrivateLink.
      + To turn off security group evaluation for PrivateLink traffic using the console, you can choose the **Security** tab, and then **Edit**. In the **Security settings**, clear **Enforce inbound rules on PrivateLink traffic**.
      + Use the following [set-security-groups](https://docs.amazonaws.cn/cli/latest/reference/elbv2/set-security-groups.html) command to turn off security group evaluation for PrivateLink traffic:

        ```
        aws elbv2 set-security-groups --load-balancer-arn arn:aws-cn:elasticloadbalancing:us-west-2:111122223333:loadbalancer/net/my-loadbalancer/abc12345 \
          --security-groups sg-123345a --enforce-security-group-inbound-rules-on-private-link-traffic off
        ```

**Note**  
Do not add any dependencies to API Gateway CIDRs as they are bound to change without notice.

# Grant permissions for API Gateway to create a VPC link (legacy)


**Note**  
The following implementation of private integrations uses VPC links V1. VPC links V1 are legacy resources. We recommend that you use [VPC links V2 for REST APIs](apigateway-vpc-links-v2.md).

For you or a user in your account to create and maintain a VPC link, you or the user must have permissions to create, delete, and view VPC endpoint service configurations, change VPC endpoint service permissions, and examine load balancers. To grant such permissions, use the following steps. 

**To grant permissions to create, update, and delete a VPC link**

1. Create an IAM policy similar to the following:

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "apigateway:POST",
                   "apigateway:GET",
                   "apigateway:PATCH",
                   "apigateway:DELETE"
               ],
               "Resource": [
                   "arn:aws-cn:apigateway:us-east-1::/vpclinks",
                   "arn:aws-cn:apigateway:us-east-1::/vpclinks/*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "elasticloadbalancing:DescribeLoadBalancers"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "ec2:CreateVpcEndpointServiceConfiguration",
                   "ec2:DeleteVpcEndpointServiceConfigurations",
                   "ec2:DescribeVpcEndpointServiceConfigurations",
                   "ec2:ModifyVpcEndpointServicePermissions"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

   If you want to enable tagging for your VPC link, make sure to allow tagging operations. For more information, see [Allow tagging operations](apigateway-tagging-iam-policy.md#allow-tagging).

1. Create or choose an IAM role and attach the preceding policy to the role.

1. Assign the IAM role to you or a user in your account who is creating VPC links.

# Set up an API Gateway API with private integrations using the Amazon CLI (legacy)
Set up an API with private integrations using Amazon CLI (legacy)

**Note**  
The following implementation of private integrations uses VPC links V1. VPC links V1 are legacy resources. We recommend that you use [VPC links V2 for REST APIs](apigateway-vpc-links-v2.md).

The following tutorial shows how to use the Amazon CLI to create a VPC link and a private integration. The following prerequisites are required:
+ You need an Network Load Balancer created and configured with your VPC source as the target. For more information, see [Set up a Network Load Balancer for API Gateway private integrations (legacy)](set-up-nlb-for-vpclink-using-console.md). This must be in the same Amazon Web Services account as your API. You need the Network Load Balancer ARN to create your VPC link.
+ To create and manage a `VpcLink`, you need the permissions to create a `VpcLink` in your API. You don't need the permissions to use the `VpcLink`. For more information, see [Grant permissions for API Gateway to create a VPC link (legacy)](grant-permissions-to-create-vpclink.md).

**To set up an API with the private integration using Amazon CLI**

1. Use the following [create-vpc-link](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-vpc-link.html) command to create a `VpcLink` targeting the specified Network Load Balancer:

   ```
   aws apigateway create-vpc-link \
       --name my-test-vpc-link \
       --target-arns arn:aws-cn:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/my-vpclink-test-nlb/1234567890abcdef
   ```

   The output of this command acknowledges the receipt of the request and shows the `PENDING` status for the `VpcLink` being created.

   ```
   {
       "status": "PENDING", 
       "targetArns": [
           "arn:aws-cn:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/my-vpclink-test-nlb/1234567890abcdef"
       ], 
       "id": "gim7c3", 
       "name": "my-test-vpc-link"
   }
   ```

   It takes 2-4 minutes for API Gateway to finish creating the `VpcLink`. When the operation finishes successfully, the `status` is `AVAILABLE`. You can verify this by using the following [get-vpc-link](https://docs.amazonaws.cn/cli/latest/reference/apigateway/get-vpc-link.html) command:

   ```
   aws apigateway get-vpc-link --vpc-link-id gim7c3
   ```

   If the operation fails, you get a `FAILED` status, with the `statusMessage` containing the error message. For example, if you attempt to create a `VpcLink` with a Network Load Balancer that is already associated with a VPC endpoint, you get the following on the `statusMessage` property:

   ```
   "NLB is already associated with another VPC Endpoint Service"
   ```

   After the `VpcLink` is created successfully, you can create an API and integrate it with the VPC resource through the `VpcLink`. 

   Note the `id` value of the newly created `VpcLink`. In this example output, it's `gim7c3`. You need it to set up the private integration.

1. Use the following [create-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-rest-api.html) command to create an API Gateway [https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource:

   ```
   aws apigateway create-rest-api --name 'My VPC Link Test'
   ```

   Note the `RestApi`'s `id` value and the `RestApi`'s `rootResourceId` value in the returned result. You need this value to perform further operations on the API. 

   Next, you create an API with only a `GET` method on the root resource (`/`) and integrate the method with the `VpcLink`.

1. Use the following [put-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-method.html) command to create the `GET /` method:

   ```
   aws apigateway put-method \
          --rest-api-id  abcdef123 \
          --resource-id skpp60rab7 \
          --http-method GET \
          --authorization-type "NONE"
   ```

   If you don't use the proxy integration with the `VpcLink`, you must also set up at least a method response of the `200` status code. You use the proxy integration here.

1. After you create the `GET /` method, you set up the integration. For a private integration, you use the `connection-id` parameter to provide the `VpcLink` ID. You can use either a stage variable or directly enter the `VpcLink` ID. The `uri` parameter is not used for routing requests to your endpoint, but is used for setting the `Host` header and for certificate validation. 

------
#### [ Use the VPC link ID ]

   Use the following [put-integration](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-integration.html) command to use the `VpcLink` ID directly in the integration:

   ```
   aws apigateway put-integration \
       --rest-api-id abcdef123 \
       --resource-id skpp60rab7 \
       --uri 'http://my-vpclink-test-nlb-1234567890abcdef.us-west-2.amazonaws.com' \
       --http-method GET \
       --type HTTP_PROXY \
       --integration-http-method GET \
       --connection-type VPC_LINK \
       --connection-id gim7c3
   ```

------
#### [ Use a stage variable ]

   Use the following [put-integration](https://docs.amazonaws.cn/cli/latest/reference/apigateway/put-integration.html) command to use a stage variable to reference the VPC link ID. When you deploy your API to a stage, you set the VPC link ID.

   ```
   aws apigateway put-integration \
       --rest-api-id abcdef123 \
       --resource-id skpp60rab7 \
       --uri 'http://my-vpclink-test-nlb-1234567890abcdef.us-west-2.amazonaws.com' \
       --http-method GET \
       --type HTTP_PROXY \
       --integration-http-method GET \
       --connection-type VPC_LINK \
       --connection-id "\${stageVariables.vpcLinkId}"
   ```

   Make sure to double-quote the stage variable expression (`${stageVariables.vpcLinkId}`) and escape the `$` character.

------

   At any point, you can also update the integration to change the `connection-id`. Use the following [update-integration](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-integration.html) command to update your integration:

   ```
    aws apigateway update-integration \
       --rest-api-id abcdef123 \
       --resource-id skpp60rab7 \
       --http-method GET \
       --patch-operations '[{"op":"replace","path":"/connectionId","value":"${stageVariables.vpcLinkId}"}]'
   ```

   Make sure to use a stringified JSON list as the `patch-operations` parameter value.

   Because you used the private proxy integration, your API is now ready for deployment and for test runs.

1. If you used the stage variable to define your `connection-id`, you need to deploy your API to test it. Use the following [create-deployment](https://docs.amazonaws.cn/cli/latest/reference/apigateway/create-deployment.html) command to deploy your API with a stage variable:

   ```
   aws apigateway create-deployment \
       --rest-api-id abcdef123 \
       --stage-name test \
       --variables vpcLinkId=gim7c3
   ```

   To update the stage variable with a different `VpcLink` ID, such as `asf9d7`, use the following [update-stage](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-stage.html) command:

   ```
   aws apigateway update-stage \
       --rest-api-id abcdef123 \
       --stage-name test \
       --patch-operations op=replace,path='/variables/vpcLinkId',value='asf9d7'
   ```

   When you hardcode the `connection-id` property with the `VpcLink` ID literal, you don't need to deploy your API to test it. Use the [test-invoke-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/test-invoke-method.html) command to test your API before it is deployed. 

1. Use the following command to invoke your API:

   ```
   curl -X GET https://abcdef123.execute-api.us-west-2.amazonaws.com/test
   ```

   Alternatively, you can enter your API's invoke-URL in a web browser to view the result.

# API Gateway accounts used for private integrations (legacy)


The following region-specific API Gateway account IDs are automatically added to your VPC endpoint service as `AllowedPrincipals` when you create a `VpcLink`.


| **Region** | **Account ID** | 
| --- | --- | 
| cn-north-1 | 643738280308 | 
| cn-northwest-1 | 020741727910 | 

# Mock integrations for REST APIs in API Gateway
Mock integration

Amazon API Gateway supports mock integrations for API methods. This feature enables API developers to generate API responses from API Gateway directly, without the need for an integration backend. As an API developer, you can use this feature to unblock dependent teams that need to work with an API before the project development is complete. You can also use this feature to provision a landing page for your API, which can provide an overview of and navigation to your API. For an example of such a landing page, see the integration request and response of the GET method on the root resource of the example API discussed in [Tutorial: Create a REST API by importing an example](api-gateway-create-api-from-example.md).

As an API developer, you decide how API Gateway responds to a mock integration request. For this, you configure the method's integration request and integration response to associate a response with a given status code. For a method with the mock integration to return a `200` response, configure the integration request body mapping template to return the following.

```
{"statusCode": 200}
```

Configure a `200` integration response to have the following body mapping template, for example:

```
{
    "statusCode": 200,
    "message": "Go ahead without me."
}
```

 Similarly, for the method to return, for example, a `500` error response, set up the integration request body mapping template to return the following.

```
{"statusCode": 500}
```

Set up a `500` integration response with, for example, the following mapping template: 

```
{
    "statusCode": 500,
    "message": "The invoked method is not supported on the API resource."
}
```

Alternatively, you can have a method of the mock integration return the default integration response without defining the integration request mapping template. The default integration response is the one with an undefined **HTTP status regex**. Make sure appropriate passthrough behaviors are set.

**Note**  
Mock integrations aren't intended to support large response templates. If you need them for your use case, you should consider using a Lambda integration instead.

Using an integration request mapping template, you can inject application logic to decide which mock integration response to return based on certain conditions. For example, you could use a `scope` query parameter on the incoming request to determine whether to return a successful response or an error response:

```
{
  #if( $input.params('scope') == "internal" )
    "statusCode": 200
  #else
    "statusCode": 500
  #end
}
```

This way, the method of the mock integration lets internal calls to go through while rejecting other types of calls with an error response. 



In this section, we describe how to use the API Gateway console to enable the mock integration for an API method.

**Topics**
+ [

# Enable mock integration using the API Gateway console
](how-to-mock-integration-console.md)

# Enable mock integration using the API Gateway console


You must have a method available in API Gateway. Follow the instructions in [Tutorial: Create a REST API with an HTTP non-proxy integration](api-gateway-create-api-step-by-step.md).

1. Choose an API resource and choose **Create method**.

   To create the method, do the following:

   1. For **Method type**, select a method. 

   1. For **Integration type**, select **Mock**.

   1. Choose **Create method**. 

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

   1. Choose **URL query string parameters**. Choose **Add query string** and for **Name**, enter **scope**. This query parameter determines if the caller is internal or otherwise.

   1. Choose **Save**.

1. On the **Method response** tab, choose **Create response**, and then do the following:

   1. For **HTTP Status**, enter **500**.

   1. Choose **Save**.

1. On the **Integration request** tab, for **Integration request settings**, 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:

      ```
      {
        #if( $input.params('scope') == "internal" )
          "statusCode": 200
        #else
          "statusCode": 500
        #end
      }
      ```

   1. Choose **Save**.

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

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

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

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

      ```
      {
          "statusCode": 200,
          "message": "Go ahead without me"
      }
      ```

   1. Choose **Save**.

1. Choose **Create response**.

   To create a 500 response, do the following:

   1. For **HTTP status regex**, enter **5\$1d\$12\$1**. 

   1. For **Method response status**, select **500**.

   1. Choose **Save**.

   1. For **5\$1d\$12\$1 - Response**, choose **Edit**. 

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

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

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

      ```
      {
          "statusCode": 500,
          "message": "The invoked method is not supported on the API resource."
      }
      ```

   1. Choose **Save**.

1.  Choose the **Test** tab. You might need to choose the right arrow button to show the tab. To test your mock integration, do the following:

   1. Enter `scope=internal` under **Query strings**. Choose **Test**. The test result shows:

      ```
      Request: /?scope=internal
      Status: 200
      Latency: 26 ms
      Response Body
      
      {
        "statusCode": 200,
        "message": "Go ahead without me"
      }
      
      Response Headers
      
      {"Content-Type":"application/json"}
      ```

   1. Enter `scope=public` under `Query strings` or leave it blank. Choose **Test**. The test result shows:

      ```
      Request: /
      Status: 500
      Latency: 16 ms
      Response Body
      
      {
        "statusCode": 500,
        "message": "The invoked method is not supported on the API resource."
      }
      
      Response Headers
      
      {"Content-Type":"application/json"}
      ```

You can also return headers in a mock integration response by first adding a header to the method response and then setting up a header mapping in the integration response. In fact, this is how the API Gateway console enables CORS support by returning CORS required headers.

# Request validation for REST APIs in API Gateway
Request validation

 You can configure API Gateway to perform basic validation of an API request before proceeding with the integration request. When the validation fails, API Gateway immediately fails the request, returns a 400 error response to the caller, and publishes the validation results in CloudWatch Logs. This reduces unnecessary calls to the backend. More importantly, it lets you focus on the validation efforts specific to your application. You can validate a request body by verifying that required request parameters are valid and non-null or by specifying a model schema for more complicated data validation.

**Topics**
+ [

## Overview of basic request validation in API Gateway
](#api-gateway-request-validation-basic-definitions)
+ [

# Data models for REST APIs
](models-mappings-models.md)
+ [

# Set up basic request validation in API Gateway
](api-gateway-request-validation-set-up.md)
+ [

# Amazon CloudFormation template of a sample API with basic request validation
](api-gateway-request-validation-sample-cloudformation.md)

## Overview of basic request validation in API Gateway


 API Gateway can perform the basic request validation, so that you can focus on app-specific validation in the backend. For validation, API Gateway verifies either or both of the following conditions: 
+ The required request parameters in the URI, query string, and headers of an incoming request are included and not blank. API Gateway only checks the existence of a parameter and doesn't check the type or format.
+  The applicable request payload adheres to the configured [JSON schema](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04) request of the method for a given content type. If no matching content type is found, request validation is not performed. To use the same model regardless of the content type, set the content type for your data model to `$default`.

To turn on validation, you specify validation rules in a [request validator](https://docs.amazonaws.cn/apigateway/latest/api/API_RequestValidator.html), add the validator to the API's [map of request validators](https://docs.amazonaws.cn/apigateway/latest/api/API_RequestValidator.html), and assign the validator to individual API methods. 

**Note**  
Request body validation and [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md) are two separate topics. When a request payload does not have a matching model schema, you can choose to passthrough or block the original payload. For more information, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md).

# Data models for REST APIs


In API Gateway, a model defines the data structure of a payload. In API Gateway, models are defined using the [JSON schema draft 4](https://tools.ietf.org/html/draft-zyp-json-schema-04). The following JSON object is sample data in the Pet Store example.

```
{
    "id": 1,
    "type": "dog",
    "price": 249.99
}
```

The data contains the `id`, `type`, and `price` of the pet. A model of this data allows you to:
+ Use basic request validation.
+ Create mapping templates for data transformation.
+ Create a user-defined data type (UDT) when you generate an SDK.

![\[Example JSON data model for PetStore API.\]](http://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/images/how-to-validate-requests.png)


In this model:

1. The `$schema` object represents a valid JSON Schema version identifier. This schema is the JSON Schema draft v4.

1. The `title` object is a human-readable identifier for the model. This title is `PetStoreModel`.

1.  The `required` validation keyword requires `type`, and `price` for basic request validation.

1. The `properties` of the model are `id`, `type`, and `price`. Each object has properties that are described in the model.

1. The object `type` can have only the values `dog`, `cat`, or `fish`.

1. The object `price` is a number and is constrained with a `minimum` of 25 and a `maximum` of 500.

## PetStore model


```
1 {
2 "$schema": "http://json-schema.org/draft-04/schema#",
3  "title": "PetStoreModel",
4  "type" : "object",
5  "required" : [ "price", "type" ],
6  "properties" : {
7    "id" : {
8      "type" : "integer"
9    },
10    "type" : {
11      "type" : "string",
12      "enum" : [ "dog", "cat", "fish" ]
13    },
14    "price" : {
15      "type" : "number",
16      "minimum" : 25.0,
17      "maximum" : 500.0
18    }
19  }
20 }
```

In this model:

1. On line 2, the `$schema` object represents a valid JSON Schema version identifier. This schema is the JSON Schema draft v4.

1. On line 3, the `title` object is a human-readable identifier for the model. This title is `PetStoreModel`.

1.  On line 5, the `required` validation keyword requires `type`, and `price` for basic request validation.

1.  On lines 6 -- 17, the `properties` of the model are `id`, `type`, and `price`. Each object has properties that are described in the model.

1. On line 12, the object `type` can have only the values `dog`, `cat`, or `fish`.

1. On lines 14 -- 17, the object `price` is a number and is constrained with a `minimum` of 25 and a `maximum` of 500.

## Creating more complex models


 You can use the `$ref` primitive to create reusable definitions for longer models. For example, you can create a definition called `Price` in the `definitions` section describing the `price` object. The value of `$ref` is the `Price` definition. 

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStoreModelReUsableRef",
  "required" : ["price", "type" ],
  "type" : "object",
  "properties" : {
    "id" : {
      "type" : "integer"
    },
    "type" : {
      "type" : "string",
      "enum" : [ "dog", "cat", "fish" ]
    },
    "price" : {
        "$ref": "#/definitions/Price"
    }
  },
  "definitions" : {
      "Price": {
        "type" : "number",
        "minimum" : 25.0,
        "maximum" : 500.0
            }
      }
}
```

You can also reference another model schema defined in an external model file. Set the value of the `$ref` property to the location of the model. In the following example, the `Price` model is defined in the `PetStorePrice` model in API `a1234`.

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStorePrice",
  "type": "number",
  "minimum": 25,
  "maximum": 500
}
```

The longer model can reference the `PetStorePrice` model.

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStoreModelReusableRefAPI",
  "required" : [ "price", "type" ],
  "type" : "object",
  "properties" : {
    "id" : {
      "type" : "integer"
    },
    "type" : {
      "type" : "string",
      "enum" : [ "dog", "cat", "fish" ]
    },
    "price" : {
        "$ref": "https://apigateway.amazonaws.com/restapis/a1234/models/PetStorePrice"
    }
  }
}
```

## Using output data models


If you transform your data, you can define a payload model in the integration response. A payload model can be used when you generate an SDK. For strongly typed languages, such as Java, Objective-C, or Swift, the object corresponds to a user-defined data type (UDT). API Gateway creates a UDT if you provide it with a data model when you generate an SDK. For more information about data transformations, see [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).

The following example is output data from an integration 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
  }
]
}
```

The following example is a payload model that describes the output data.

```
{
"$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PetStoreOutputModel",
  "type" : "object",
  "required" : [ "description", "askingPrice" ],
  "properties" : {
    "description" : {
      "type" : "string"
    },
    "askingPrice" : {
      "type" : "number",
      "minimum" : 25.0,
      "maximum" : 500.0
    }
  }
}
```

With this model, you can call an SDK to retrieve the `description` and `askingPrice` property values by reading the `PetStoreOutputModel[i].description` and `PetStoreOutputModel[i].askingPrice` properties. If no model is provided, API Gateway uses the empty model to create a default UDT. 

## Next steps

+ This section provides resources that you can use to gain more knowledge about the concepts presented in this topic.

  You can follow the request validation tutorials:
  + [Set up request validation using the API Gateway console](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-in-console)
  +  [Set up basic request validation using the Amazon CLI](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-cli)
  +  [Set up basic request validation using an OpenAPI definition](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-importing-swagger)
+  For more information about data transformation and mapping templates, [Mapping template transformations for REST APIs in API Gateway](models-mappings.md).

# Set up basic request validation in API Gateway


 This section shows how to set up request validation for API Gateway using the console, Amazon CLI, and an OpenAPI definition.

**Topics**
+ [

## Set up request validation using the API Gateway console
](#api-gateway-request-validation-setup-in-console)
+ [

## Set up basic request validation using the Amazon CLI
](#api-gateway-request-validation-setup-cli)
+ [

## Set up basic request validation using an OpenAPI definition
](#api-gateway-request-validation-setup-importing-swagger)

## Set up request validation using the API Gateway console


 You can use the API Gateway console to validate a request by selecting one of three validators for an API request: 
+ **Validate body**.
+ **Validate query string parameters and headers**.
+ **Validate body, query string parameters, and headers**.

 When you apply one of the validators on an API method, the API Gateway console adds the validator to the API's [RequestValidators](https://docs.amazonaws.cn/apigateway/latest/api/API_RequestValidator.html) map.

To follow this tutorial, you'll use an Amazon CloudFormation template to create an incomplete API Gateway API. This API has a `/validator` resource with `GET` and `POST` methods. Both methods are integrated with the `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP endpoint. You will configure two kinds of request validation:
+ In the `GET` method, you will configure request validation for URL query string parameters.
+ In the `POST` method, you will configure request validation for the request body.

 This will allow only certain API calls to pass through to the API. 

Download and unzip [the app creation template for Amazon CloudFormation](samples/request-validation-tutorial-console.zip). You'll use this template to create an incomplete API. You will finish the rest of the steps in the API Gateway console. 

**To create an Amazon CloudFormation stack**

1. Open the Amazon CloudFormation console at [https://console.amazonaws.cn/cloudformation](https://console.amazonaws.cn/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 **request-validation-tutorial-console** and then choose **Next**.

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

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

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

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

**To select your newly created API**

1. Select the newly created **request-validation-tutorial-console** stack.

1. Choose **Resources**.

1. Under **Physical ID**, choose your API. This link will direct you to the API Gateway console.

Before you modify the `GET` and `POST` methods, you must create a model.

**To create a model**

1. A model is required to use request validation on the body of an incoming request. To create a model, in the main navigation pane, choose **Models**.

1. Choose **Create model**.

1. For **Name**, enter **PetStoreModel**.

1. For **Content Type**, enter **application/json**. If no matching content type is found, request validation is not performed. To use the same model regardless of the content type, enter **\$1default**.

1. For **Description**, enter **My PetStore Model** as the model description.

1. For **Model schema**, paste the following model into the code editor, and choose **Create**. 

   ```
   {
     "type" : "object",
     "required" : [ "name", "price", "type" ],
     "properties" : {
       "id" : {
         "type" : "integer"
       },
       "type" : {
         "type" : "string",
         "enum" : [ "dog", "cat", "fish" ]
       },
       "name" : {
         "type" : "string"
       },
       "price" : {
         "type" : "number",
         "minimum" : 25.0,
         "maximum" : 500.0
       }
     }
   }
   ```

For more information about the model, see [Data models for REST APIs](models-mappings-models.md). 

**To configure request validation for a `GET` method**

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

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

1. For **Request validator**, select **Validate query string parameters and headers**.

1. Under **URL query string parameters**, do the following: 

   1. Choose **Add query string**.

   1. For **Name**, enter **petType**.

   1. Turn on **Required**.

   1. Keep **Caching** turned off. 

1. Choose **Save**.

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

1. Under **URL query string parameters**, do the following: 

   1. Choose **Add query string**.

   1. For **Name**, enter **petType**.

   1. For **Mapped from**, enter **method.request.querystring.petType**. This maps the **petType** to the pet's type.

      For more information about data mapping, see [ the data mapping tutorial](set-up-data-transformations-in-api-gateway.md#mapping-example-console).

   1. Keep **Caching** turned off. 

1. Choose **Save**.

**To test request validation for the `GET` method**

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

1. For **Query strings**, enter **petType=dog**, and then choose **Test**.

1. The method test will return `200 OK` and a list of dogs.

   For information about how to transform this output data, see the [data mapping tutorial.](set-up-data-transformations-in-api-gateway.md#mapping-example-console)

1. Remove **petType=dog** and choose **Test**. 

1.  The method test will return a `400` error with the following error message: 

   ```
   {
     "message": "Missing required request parameters: [petType]"
   }
   ```

**To configure request validation for the `POST` method**

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

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

1. For **Request validator**, select **Validate body**.

1. Under **Request body**, choose **Add model**.

1. For **Content type**, enter **application/json**. If no matching content type is found, request validation is not performed. To use the same model regardless of the content type, enter `$default`.

    For **Model**, select **PetStoreModel**.

1. Choose **Save**.

**To test request validation for a `POST` method**

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

1. For **Request body** paste the following into the code editor:

   ```
   {
     "id": 2,
     "name": "Bella",
     "type": "dog",
     "price": 400
   }
   ```

    Choose **Test**.

1. The method test will return `200 OK` and a success message. 

1. For **Request body** paste the following into the code editor:

   ```
   {
     "id": 2,
     "name": "Bella",
     "type": "dog",
     "price": 4000
   }
   ```

    Choose **Test**. 

1.  The method test will return a `400` error with the following error message:

   ```
   {
    "message": "Invalid request body"
   }
   ```

    At the bottom of the test logs, the reason for the invalid request body is returned. In this case, the price of the pet was outside the maximum specified in the model. 

**To delete an Amazon CloudFormation stack**

1. Open the Amazon CloudFormation console at [https://console.amazonaws.cn/cloudformation](https://console.amazonaws.cn/cloudformation/).

1. Select your Amazon CloudFormation stack.

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

### Next steps

+ For information about how to transform output data and perform more data mapping, see the [data mapping tutorial](set-up-data-transformations-in-api-gateway.md#mapping-example-console).
+ Follow the [ Set up basic request validation using the Amazon CLI](#api-gateway-request-validation-setup-cli) tutorial, to do similar steps using the Amazon CLI. 

## Set up basic request validation using the Amazon CLI


You can create a validator to set up request validation using the Amazon CLI. To follow this tutorial, you'll use an Amazon CloudFormation template to create an incomplete API Gateway API. 

**Note**  
This is not the same Amazon CloudFormation template as the console tutorial.

 Using a pre-exposed `/validator`resource, you will create `GET` and `POST` methods. Both methods will be integrated with the `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP endpoint. You will configure the following two request validations:
+ On the `GET` method, you will create a `params-only` validator to validate URL query string parameters.
+ On the `POST` method, you will create a `body-only` validator to validate the request body.

 This will allow only certain API calls to pass through to the API. 

**To create an Amazon CloudFormation stack**

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

To complete the following tutorial, you need the [Amazon Command Line Interface (Amazon CLI) version 2](https://docs.amazonaws.cn/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 Amazon CloudFormation stack.

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

1. Amazon 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 Amazon CloudFormation stack.

   ```
   aws cloudformation describe-stacks --stack-name request-validation-tutorial-cli
   ```

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

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

   The output values are the following:
   + ApiId, which is the ID for the API. For this tutorial, the API ID is `abc123`.
   + ResourceId, which is the ID for the validator resource where the `GET` and `POST` methods are exposed. For this tutorial, the Resource ID is `efg456`

**To create the request validators and import a model**

1. A validator is required to use request validation with the Amazon CLI. Use the following command to create a validator that validates only request parameters. 

   ```
   aws apigateway create-request-validator --rest-api-id abc123 \
         --no-validate-request-body \
         --validate-request-parameters \
         --name params-only
   ```

   Note the ID of the `params-only` validator.

1.  Use the following command to create a validator that validates only the request body. 

   ```
   aws apigateway create-request-validator --rest-api-id abc123 \
         --validate-request-body \
         --no-validate-request-parameters \
         --name body-only
   ```

   Note the ID of the `body-only` validator.

1.  A model is required to use request validation on the body of an incoming request. Use the following command to import a model.

   ```
   aws apigateway create-model --rest-api-id abc123 --name PetStoreModel --description 'My PetStore Model' --content-type 'application/json' --schema '{"type": "object", "required" : [ "name", "price", "type" ], "properties" : { "id" : {"type" : "integer"},"type" : {"type" : "string", "enum" : [ "dog", "cat", "fish" ]},"name" : { "type" : "string"},"price" : {"type" : "number","minimum" : 25.0, "maximum" : 500.0}}}}' 
   ```

   If no matching content type is found, request validation is not performed. To use the same model regardless of the content type, specify `$default` as the key.

**To create the `GET` and `POST` methods**

1. Use the following command to add the `GET` HTTP method on the `/validate` resource. This command creates the `GET`method, adds the `params-only` validator, and sets the query string `petType` as required. 

   ```
   aws apigateway put-method --rest-api-id abc123 \
          --resource-id efg456 \
          --http-method GET \
          --authorization-type "NONE" \
          --request-validator-id aaa111 \
          --request-parameters "method.request.querystring.petType=true"
   ```

   Use the following command to add the `POST` HTTP method on the `/validate` resource. This command creates the `POST`method, adds the `body-only` validator, and attaches the model to the body-only validator. 

   ```
   aws apigateway put-method --rest-api-id abc123 \
          --resource-id efg456 \
          --http-method POST \
          --authorization-type "NONE" \
          --request-validator-id bbb222 \
          --request-models 'application/json'=PetStoreModel
   ```

1.  Use the following command to set up the `200 OK` response of the `GET /validate` method. 

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

    Use the following command to set up the `200 OK` response of the `POST /validate` 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 set up an `Integration` with a specified HTTP endpoint for the `GET /validation` method. 

   ```
   aws apigateway put-integration --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method GET \
               --type HTTP \
               --integration-http-method GET \
               --request-parameters '{"integration.request.querystring.type" : "method.request.querystring.petType"}' \
               --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   ```

    Use the following command to set up an `Integration` with a specified HTTP endpoint for the `POST /validation` method. 

   ```
   aws apigateway put-integration --rest-api-id abc123  \
                 --resource-id efg456 \
                 --http-method POST \
                 --type HTTP \
                 --integration-http-method GET \
                 --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   ```

1.  Use the following command to set up an integration response for the `GET /validation` method. 

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
                 --resource-id efg456\
                 --http-method GET \
                 --status-code 200 \
                 --selection-pattern ""
   ```

    Use the following command to set up an integration response for the `POST /validation` method.

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

**To test the API**

1. To test the `GET` method, which will perform request validation for the query strings, use the following command:

   ```
   aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method GET \
               --path-with-query-string '/validate?petType=dog'
   ```

   The result will return a `200 OK` and list of dogs.

1. Use the following command to test without including the query string `petType`

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

   The result will return a `400` error.

1. To test the `POST` method, which will perform request validation for the request body, use the following command:

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

   The result will return a `200 OK` and a success message. 

1. Use the following command to test using an invalid body.

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

   The result will return a `400` error, as the price of the dog is over the maximum price defined by the model.

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

  ```
  aws cloudformation delete-stack  --stack-name request-validation-tutorial-cli
  ```

## Set up basic request validation using an OpenAPI definition


 You can declare a request validator at the API level by specifying a set of the [x-amazon-apigateway-request-validators.requestValidator object](api-gateway-swagger-extensions-request-validators.requestValidator.md) objects in the [x-amazon-apigateway-request-validators object](api-gateway-swagger-extensions-request-validators.md) map to select what part of the request will be validated. In the example OpenAPI definition, there are two validators: 
+ `all` validator which validates both the body, using the `RequestBodyModel` data model, and the parameters.

  The `RequestBodyModel` data model requires that the input JSON object contains the `name`, `type`, and `price` properties. The `name` property can be any string, `type` must be one of the specified enumeration fields (`["dog", "cat", "fish"]`), and `price` must range between 25 and 500. The `id` parameter is not required. 
+ `param-only` which validates only the parameters.

 To turn a request validator on all methods of an API, specify an [x-amazon-apigateway-request-validator property](api-gateway-swagger-extensions-request-validator.md) property at the API level of the OpenAPI definition. In the example OpenAPI definition, the `all` validator is used on all API methods, unless otherwise overridden. When using a model to validate the body, if no matching content type is found, request validation is not performed. To use the same model regardless of the content type, specify `$default` as the key.

To turn on a request validator on an individual method, specify the `x-amazon-apigateway-request-validator` property at the method level. In the example, OpenAPI definition, the `param-only` validator overwrites the `all` validator on the `GET` method.



To import the OpenAPI example into API Gateway, see the following instructions to [Import a Regional API into API Gateway](import-export-api-endpoints.md) or to [Import an edge-optimized API into API Gateway](import-edge-optimized-api.md).

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

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "ReqValidators Sample",
    "version" : "1.0.0"
  },
  "servers" : [ {
    "url" : "/{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "/v1"
      }
    }
  } ],
  "paths" : {
    "/validation" : {
      "get" : {
        "parameters" : [ {
          "name" : "q1",
          "in" : "query",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "test-method-response-header" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ArrayOfError"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "params-only",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.type" : "method.request.querystring.q1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      },
      "post" : {
        "parameters" : [ {
          "name" : "h1",
          "in" : "header",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/RequestBodyModel"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "test-method-response-header" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ArrayOfError"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "all",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "POST",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.custom_h1" : "method.request.header.h1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "RequestBodyModel" : {
        "required" : [ "name", "price", "type" ],
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "dog", "cat", "fish" ]
          },
          "name" : {
            "type" : "string"
          },
          "price" : {
            "maximum" : 500.0,
            "minimum" : 25.0,
            "type" : "number"
          }
        }
      },
      "ArrayOfError" : {
        "type" : "array",
        "items" : {
          "$ref" : "#/components/schemas/Error"
        }
      },
      "Error" : {
        "type" : "object"
      }
    }
  },
  "x-amazon-apigateway-request-validators" : {
    "all" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : true
    },
    "params-only" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : false
    }
  }
}
```

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

```
{
  "swagger" : "2.0",
  "info" : {
    "version" : "1.0.0",
    "title" : "ReqValidators Sample"
  },
  "basePath" : "/v1",
  "schemes" : [ "https" ],
  "paths" : {
    "/validation" : {
      "get" : {
        "produces" : [ "application/json", "application/xml" ],
        "parameters" : [ {
          "name" : "q1",
          "in" : "query",
          "required" : true,
          "type" : "string"
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "schema" : {
              "$ref" : "#/definitions/ArrayOfError"
            },
            "headers" : {
              "test-method-response-header" : {
                "type" : "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "params-only",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.type" : "method.request.querystring.q1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      },
      "post" : {
        "consumes" : [ "application/json" ],
        "produces" : [ "application/json", "application/xml" ],
        "parameters" : [ {
          "name" : "h1",
          "in" : "header",
          "required" : true,
          "type" : "string"
        }, {
          "in" : "body",
          "name" : "RequestBodyModel",
          "required" : true,
          "schema" : {
            "$ref" : "#/definitions/RequestBodyModel"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "schema" : {
              "$ref" : "#/definitions/ArrayOfError"
            },
            "headers" : {
              "test-method-response-header" : {
                "type" : "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "all",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "POST",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.custom_h1" : "method.request.header.h1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "definitions" : {
    "RequestBodyModel" : {
      "type" : "object",
      "required" : [ "name", "price", "type" ],
      "properties" : {
        "id" : {
          "type" : "integer"
        },
        "type" : {
          "type" : "string",
          "enum" : [ "dog", "cat", "fish" ]
        },
        "name" : {
          "type" : "string"
        },
        "price" : {
          "type" : "number",
          "minimum" : 25.0,
          "maximum" : 500.0
        }
      }
    },
    "ArrayOfError" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Error"
      }
    },
    "Error" : {
      "type" : "object"
    }
  },
  "x-amazon-apigateway-request-validators" : {
    "all" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : true
    },
    "params-only" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : false
    }
  }
}
```

------

# Amazon CloudFormation template of a sample API with basic request validation


 The following Amazon CloudFormation example template definition defines a sample API with request validation enabled. The API is a subset of the [PetStore API](http://petstore-demo-endpoint.execute-api.com/petstore/pets). It exposes a `POST` method to add a pet to the `pets` collection and a `GET` method to query pets by a specified type. 

 There are two request validators declared:

**`GETValidator`**  
This validator is enabled on the `GET` method. It allows API Gateway to verify that the required query parameter (`q1`) is included and not blank in the incoming request. 

**`POSTValidator`**  
This validator is enabled on the `POST` method. It allows API Gateway to verify that payload request format adheres to the specified `RequestBodyModel` when the content type is `application/json` if no matching content type is found, request validation is not performed. To use the same model regardless of the content type, specify `$default`. `RequestBodyModel` contains an additional model, `RequestBodyModelId`, to define the pet ID.

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: ReqValidatorsSample
  RequestBodyModelId:
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref Api
      ContentType: application/json
      Description: Request body model for Pet ID.
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: RequestBodyModelId
        properties:
            id:
              type: integer
  RequestBodyModel: 
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref Api
      ContentType: application/json
      Description: Request body model for Pet type, name, price, and ID.
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: RequestBodyModel
        required:
          - price
          - name
          - type
        type: object
        properties:
            id:
              "$ref": !Sub 
                - 'https://apigateway.amazonaws.com/restapis/${Api}/models/${RequestBodyModelId}'
                - Api: !Ref Api
                  RequestBodyModelId: !Ref RequestBodyModelId
            price: 
              type: number
              minimum: 25
              maximum: 500
            name:
              type: string
            type:
              type: string
              enum:
                - "dog"
                - "cat"
                - "fish"
  GETValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: params-only
      RestApiId: !Ref Api
      ValidateRequestBody: False
      ValidateRequestParameters: True 
  POSTValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: body-only
      RestApiId: !Ref Api
      ValidateRequestBody: True
      ValidateRequestParameters: False
  ValidationResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'validation'
  ValidationMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref ValidationResource
      HttpMethod: GET
      AuthorizationType: NONE
      RequestValidatorId: !Ref GETValidator
      RequestParameters:
        method.request.querystring.q1: true
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ValidationMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref ValidationResource
      HttpMethod: POST
      AuthorizationType: NONE
      RequestValidatorId: !Ref POSTValidator
      RequestModels:
        application/json : !Ref RequestBodyModel 
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: POST
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - ValidationMethodGet
      - RequestBodyModel 
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
Outputs:
  ApiRootUrl:
    Description: Root Url of the API
    Value: !Sub 'https://${Api}.execute-api.${AWS::Region}.amazonaws.com/${StageName}'
```

# Data transformations for REST APIs in API Gateway
Data transformations

**Note**  
This section explains features that you use with a non-proxy integration. However, we recommend that when possible, you use a proxy integration for your REST API. A proxy integration has a streamlined integration setup and can evolve with the backend without having to tear down the existing setup. For more information, see [Choose an API Gateway API integration type](api-gateway-api-integration-types.md).

If you use a non-proxy integration, you can use two features of API Gateway to transform your method request and your integration response. You might transform your method request if it takes a different payload format than the integration request payload. You might transform your integration response if it returns a different payload format than the format you need to return in the method response. For more information about the request lifecycle, see [Example resource for a REST API](rest-api-develop.md#rest-api-develop-example).

The following example shows a data transformation where for the header `"x-version:beta"`, the `x-version` header parameter is transformed into the `app-version` header parameter. The data transformation from `x-version` to `app-version` occurs in the integration request. That way, the integration endpoint receives the transformed header parameter value. When the integration endpoint returns a status code, the status code is transformed from `200` to `204` before the method response.

To create a data transformation, you can use the following features:

**Parameter mapping**  
In parameter mapping, you can modify integration request URL path parameters, URL query string parameters, or HTTP header values, but you can't modify the integration request payload. You can also modify HTTP response header values. Use parameter mapping to create static header values for cross origin resource sharing (CORS).   
You can use parameter mapping in your integration request for proxy and non-proxy integrations, but to use parameter mapping for an integration response, you need a non-proxy integration. Parameter mapping doesn't require any scripting in [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html). For more information, see [Parameter mapping for REST APIs in API Gateway](rest-api-parameter-mapping.md).

**Mapping template transformations**  
In mapping template transformations, you use a mapping template to map URL path parameters, URL query string parameters, HTTP headers, and the integration request or integration response body. A *mapping template* is a script expressed in [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) using [JSONPath expressions](https://goessner.net/articles/JsonPath/) and applied to the payload based on the `Content-type` header.  
With a mapping template, you can do the following:  
+ Select which data to send using integration with Amazon Web Services services, such as Amazon DynamoDB or Lambda functions, or HTTP endpoints. For more information, see [Tutorial: Modify the integration request and response for integrations to Amazon services](set-up-data-transformations-in-api-gateway.md).
+ Conditionally override an API's integration request and integration response parameters, create new header values, and override status codes. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md).
You can also specify the behavior of your API when an integration request body has `Content-type` header with no matching mapping templates. This is called integration passthrough behavior. For more information, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md). 

## Choose between parameter mapping and mapping template transformations


We recommend that you use parameter mapping to transform your data when possible. If your API requires you to change the body, or requires you to perform conditional overrides and modifications based on the incoming integration request or integration response, and you can't use a proxy integration, use mapping template transformations.

# Parameter mapping for REST APIs in API Gateway
Parameter mapping

**Note**  
If you are using an HTTP API, see [Transform API requests and responses for HTTP APIs in API Gateway](http-api-parameter-mapping.md).

In parameter mapping, you map request or response parameters. You can map parameters using parameter mapping expressions or static values. For a list of mapping expressions, see [Parameter mapping source reference for REST APIs in API Gateway](rest-api-parameter-mapping-sources.md). You can use parameter mapping in your integration request for proxy and non-proxy integrations, but to use parameter mapping for an integration response, you need a non-proxy integration.

For example, you can map the method request header parameter `puppies` to the integration request header parameter `DogsAge0`. Then, if a client sends the header `puppies:true` to your API, the integration request sends the request header `DogsAge0:true` to the integration endpoint. The following diagram shows the request lifecycle of this example.

To create this example using API Gateway, see [Example 1: Map a method request parameter to an integration request parameter](request-response-data-mappings.md#request-response-data-mappings-example-1).

 As another example, you can also map the integration response header parameter `kittens` to the method response header parameter `CatsAge0`. Then, if the integration endpoint returns `kittens:false`, the client receives the header `CatsAge0:false`. The following diagram shows the request lifecycle of this example.

**Topics**
+ [

# Parameter mapping examples for REST APIs in API Gateway
](request-response-data-mappings.md)
+ [

# Parameter mapping source reference for REST APIs in API Gateway
](rest-api-parameter-mapping-sources.md)

# Parameter mapping examples for REST APIs in API Gateway
Parameter mapping examples

The following examples show how to create parameter mapping expressions using the API Gateway console, OpenAPI, and Amazon CloudFormation templates. For an example of how to use parameter mapping to create the required CORS headers, see [CORS for REST APIs in API Gateway](how-to-cors.md). 

## Example 1: Map a method request parameter to an integration request parameter


The following example maps the method request header parameter `puppies` to the integration request header parameter `DogsAge0`. 

------
#### [ Amazon Web Services Management Console ]

**To map the method request parameter**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose a method.

   Your method must have a non-proxy integration.

1. For **Method request settings**, choose **Edit**.

1. Choose **HTTP request headers**.

1. Choose **Add header**.

1. For **Name**, enter **puppies**.

1. Choose **Save**.

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

   The Amazon Web Services Management Console automatically adds a parameter mapping from `method.request.header.puppies ` to `puppies` for you, but you need to change the **Name** to match the request header parameter that is expected by your integration endpoint.

1. For **Name**, enter **DogsAge0**.

1. Choose **Save**.

1. Redeploy your API for the changes to take effect.

The following steps show you how to verify that your parameter mapping was successful.

**(Optional) Test your parameter mapping**

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

1. For headers, enter **puppies:true**.

1. Choose **Test**.

1. In the **Logs**, the result should look like the following:

   ```
   Tue Feb 04 00:28:36 UTC 2025 : Method request headers: {puppies=true}
   Tue Feb 04 00:28:36 UTC 2025 : Method request body before transformations: 
   Tue Feb 04 00:28:36 UTC 2025 : Endpoint request URI: http://petstore-demo-endpoint.execute-api.com/petstore/pets
   Tue Feb 04 00:28:36 UTC 2025 : Endpoint request headers: {DogsAge0=true, x-amzn-apigateway-api-id=abcd1234, Accept=application/json, User-Agent=AmazonAPIGateway_aaaaaaa, X-Amzn-Trace-Id=Root=1-abcd-12344}
   ```

   The request header parameter has changed from `puppies` to `DogsAge0`.

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

 In this example, you use the [body](https://docs.amazonaws.cn/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: ParameterMappingExample
          version: "2025-02-04T00:30:41Z"
        paths:
          /pets:
            get:
              parameters:
                - name: puppies
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.DogsAge0: method.request.header.puppies
                passthroughBehavior: when_no_match
                type: http
  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" : "3.0.1",
  "info" : {
    "title" : "ParameterMappingExample",
    "version" : "2025-02-04T00:30:41Z"
  },
  "paths" : {
    "/pets" : {
      "get" : {
        "parameters" : [ {
          "name" : "puppies",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.DogsAge0" : "method.request.header.puppies"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  }
}
```

------

## Example 2: Map multiple method request parameters to different integration request parameters


The following example maps the multi-value method request query string parameter `methodRequestQueryParam` to the integration request query string parameter `integrationQueryParam` and maps the method request header parameter `methodRequestHeaderParam` to the integration request path parameter `integrationPathParam`.

------
#### [ Amazon Web Services Management Console ]

**To map the method request parameters**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose a method.

   Your method must have a non-proxy integration.

1. For **Method request settings**, choose **Edit**.

1. Choose **URL query string parameters**.

1. Choose **Add query string**.

1. For **Name**, enter **methodRequestQueryParam**.

1. Choose **HTTP request headers**.

1. Choose **Add header**.

1. For **Name**, enter **methodRequestHeaderParam**.

1. Choose **Save**.

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

1. Choose **URL path parameters**.

1. Choose **Add path parameter**.

1. For **Name**, enter **integrationPathParam**.

1. For **Mapped from**, enter **method.request.header.methodRequestHeaderParam**.

   This maps the method request header you specified in the method request to a new integration request path parameter.

1. Choose **URL query string parameters**.

1. Choose **Add query string**.

1. For **Name**, enter **integrationQueryParam**.

1. For **Mapped from**, enter **method.request.multivaluequerystring.methodRequestQueryParam**.

   This maps the multivalue query string parameter to a new single valued integration request query string parameter.

1. Choose **Save**.

1. Redeploy your API for the changes to take effect.

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

 In this example, you use the [body](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) property to import an OpenAPI definition file into API Gateway. 

The following OpenAPI definition creates the following parameter mappings for an HTTP integration:
+ The method request's header, named `methodRequestHeaderParam`, into the integration request path parameter, named `integrationPathParam`
+ The multi-value method request query string, named `methodRequestQueryParam`, into the integration request query string, named `integrationQueryParam`

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: Parameter mapping example 2
          version: "2025-01-15T19:12:31Z"
        paths:
          /:
            post:
              parameters:
                - name: methodRequestQueryParam
                  in: query
                  schema:
                    type: string
                - name: methodRequestHeaderParam
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.querystring.integrationQueryParam: method.request.multivaluequerystring.methodRequestQueryParam
                  integration.request.path.integrationPathParam: method.request.header.methodRequestHeaderParam
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                passthroughBehavior: when_no_templates
                timeoutInMillis: 29000
                type: http
  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 following parameter mappings for an HTTP integration:
+ The method request's header, named `methodRequestHeaderParam`, into the integration request path parameter, named `integrationPathParam`
+ The multi-value method request query string, named `methodRequestQueryParam`, into the integration request query string, named `integrationQueryParam`

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Parameter mapping example 2",
    "version" : "2025-01-15T19:12:31Z"
  },
  "paths" : {
    "/" : {
      "post" : {
        "parameters" : [ {
          "name" : "methodRequestQueryParam",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "methodRequestHeaderParam",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.integrationQueryParam" : "method.request.multivaluequerystring.methodRequestQueryParam",
            "integration.request.path.integrationPathParam" : "method.request.header.methodRequestHeaderParam"
          },
          "requestTemplates" : {
            "application/json" : "{\"statusCode\": 200}"
          },
          "passthroughBehavior" : "when_no_templates",
          "timeoutInMillis" : 29000,
          "type" : "http"
        }
      }
    }
  }
}
```

------

## Example 3: Map fields from the JSON request body to integration request parameters


You can also map integration request parameters from fields in the JSON request body using a [JSONPath expression](http://goessner.net/articles/JsonPath/index.html#e2). The following example maps the method request body to an integration request header named `body-header` and maps part of the request body, as expressed by a JSON expression to an integration request header named `pet-price`.

To test this example, provide an input that contains a price category, such as the following:

```
[ 
  { 
    "id": 1, 
    "type": "dog", 
    "price": 249.99 
  }
]
```

------
#### [ Amazon Web Services Management Console ]

**To map the method request parameters**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose a `POST`, `PUT`, `PATCH`, or `ANY` method.

   Your method must have a non-proxy integration.

1. For **Integration request settings**, choose **Edit**.

1. Choose **URL request headers parameters**.

1. Choose **Add request header parameter**.

1. For **Name**, enter **body-header**.

1. For **Mapped from**, enter **method.request.body**.

   This maps the method request body to a new integration request header parameter.

1. Choose **Add request header parameter**.

1. For **Name**, enter **pet-price**.

1. For **Mapped from**, enter ** method.request.body[0].price**.

   This maps a part of the method request body to a new integration request header parameter.

1. Choose **Save**.

1. Redeploy your API for the changes to take effect.

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

 In this example, you use the [body](https://docs.amazonaws.cn/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: Parameter mapping example 3
          version: "2025-01-15T19:19:14Z"
        paths:
          /:
            post:
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.pet-price: method.request.body[0].price
                  integration.request.header.body-header: method.request.body
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                passthroughBehavior: when_no_templates
                timeoutInMillis: 29000
                type: http
  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 map integration request parameters from fields in the JSON request body.

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Parameter mapping example 3",
    "version" : "2025-01-15T19:19:14Z"
  },
  "paths" : {
    "/" : {
      "post" : {
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.pet-price" : "method.request.body[0].price",
            "integration.request.header.body-header" : "method.request.body"
          },
          "requestTemplates" : {
            "application/json" : "{\"statusCode\": 200}"
          },
          "passthroughBehavior" : "when_no_templates",
          "timeoutInMillis" : 29000,
          "type" : "http"
        }
      }
    }
  }
}
```

------

## Example 4: Map the integration response to the method response


You can also map the integration response to the method response. The following example maps the integration response body to a method response header named `location`, maps the integration response header `x-app-id` to the method response header `id`, and maps the multi-valued integration response header `item` to the method response header `items`.

------
#### [ Amazon Web Services Management Console ]

**To map the integration response**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. Choose a method.

   Your method must have a non-proxy integration.

1. Choose the **Method response** tab, and then for **Response 200**, choose **Edit**.

1. For **Header name**, choose **Add header**.

1. Create three headers named **id**, **item**, and **location**.

1. Choose **Save**.

1. Choose the **Integration response** tab, and then for **Default - Response**, choose **Edit**.

1. Under **Header mappings**, enter the following.

   1. For **id**, enter **integration.response.header.x-app-id**

   1. For **item**, enter **integration.response.multivalueheader.item**

   1. For **location**, enter **integration.response.body.redirect.url**

1. Choose **Save**.

1. Redeploy your API for the changes to take effect.

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

 In this example, you use the [body](https://docs.amazonaws.cn/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: Parameter mapping example
          version: "2025-01-15T19:21:35Z"
        paths:
          /:
            post:
              responses:
                "200":
                  description: 200 response
                  headers:
                    item:
                      schema:
                        type: string
                    location:
                      schema:
                        type: string
                    id:
                      schema:
                        type: string
              x-amazon-apigateway-integration:
                type: http
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                    responseParameters:
                      method.response.header.id: integration.response.header.x-app-id
                      method.response.header.location: integration.response.body.redirect.url
                      method.response.header.item: integration.response.multivalueheader.item
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                passthroughBehavior: when_no_templates
                timeoutInMillis: 29000
  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 maps the integration response to the method response.

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Parameter mapping example",
    "version" : "2025-01-15T19:21:35Z"
  },
  "paths" : {
    "/" : {
      "post" : {
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "item" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "location" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "id" : {
                "schema" : {
                  "type" : "string"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "type" : "http",
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.id" : "integration.response.header.x-app-id",
                "method.response.header.location" : "integration.response.body.redirect.url",
                "method.response.header.item" : "integration.response.multivalueheader.item"
              }
            }
          },
          "requestTemplates" : {
            "application/json" : "{\"statusCode\": 200}"
          },
          "passthroughBehavior" : "when_no_templates",
          "timeoutInMillis" : 29000
        }
      }
    }
  }
}
```

------

# Parameter mapping source reference for REST APIs in API Gateway
Parameter mapping source reference

When you create a parameter mapping, you specify the method request or integration response parameters to modify and you specify how to modify those parameters.

The following table shows the method request parameters that you can map, and the expression to create the mapping. In these expressions, *name* is the name of a method request parameter. For example, to map the request header parameter `puppies`, use the expression `method.request.header.puppies`. Your expression must match the regular expression `'^[a-zA-Z0-9._$-]+$]'`. You can use parameter mapping in your integration request for proxy and non-proxy integrations. 


| **Mapped data source** | **Mapping expression** | 
| --- | --- | 
| Method request path | method.request.path.name | 
| Method request query string | method.request.querystring.name | 
| Multi-value method request query string | method.request.multivaluequerystring.name | 
| Method request header | method.request.header.name | 
| Multi-value method request header | method.request.multivalueheader.name | 
| Method request body | method.request.body | 
| Method request body (JsonPath) | `method.request.body.JSONPath_EXPRESSION`. *JSONPath\$1EXPRESSION* is a JSONPath expression for a JSON field of the body of a request. For more information, see [JSONPath expression](http://goessner.net/articles/JsonPath/index.html#e2).  | 
| Stage variables | stageVariables.name | 
| Context variables |  `context.name` The name must be one of the [supported context variables](api-gateway-mapping-template-reference.md#context-variable-reference). | 
| Static value | `'static_value'`. The *static\$1value* is a string literal and must be enclosed within a pair of single quotes. For example, `'https://www.example.com'`. | 

The following table shows the integration response parameters that you can map and the expression to create the mapping. In these expressions, *name* is the name of an integration response parameter. You can map method response headers from any integration response header or integration response body, \$1context variables, or static values. To use parameter mapping for an integration response, you need a non-proxy integration.


| Mapped data source | Mapping expression | 
| --- | --- | 
| Integration response header | integration.response.header.name | 
| Integration response header | integration.response.multivalueheader.name | 
| Integration response body | integration.response.body | 
| Integration response body (JsonPath) | `integration.response.body.JSONPath_EXPRESSION` *JSONPath\$1EXPRESSION* is a JSONPath expression for a JSON field of the body of a response. For more information, see [JSONPath expression](http://goessner.net/articles/JsonPath/index.html#e2). | 
| Stage variable | stageVariables.name | 
| Context variable |  `context.name` The name must be one of the [supported context variables](api-gateway-mapping-template-reference.md#context-variable-reference). | 
| Static value | ` 'static_value'` The *static\$1value* is a string literal and must be enclosed within a pair of single quotes. For example, `'https://www.example.com'`. | 

# Mapping template transformations for REST APIs in API Gateway
Mapping template transformations

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.

The following sections explain the request and response lifecycle.

## Method request and integration request


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


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
Method request behavior for payloads without mapping templates

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.amazonaws.cn/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.amazonaws.cn/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.amazonaws.cn/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
Additional mapping template example

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


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


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
Override your API's request and response parameters and status codes

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


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.

------
#### [ Amazon Web Services Management Console ]

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

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/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`.

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

 In this example, you use the [body](https://docs.amazonaws.cn/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


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

------
#### [ Amazon Web Services 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.amazonaws.cn/apigateway](https://console.amazonaws.cn/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}
   ```

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

 In this example, you use the [body](https://docs.amazonaws.cn/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 Amazon services


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 Amazon CLI.

**Topics**
+ [

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

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

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

## Set up data transformation using the API Gateway console


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 Amazon 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 Amazon CloudFormation stack**

1. Open the Amazon CloudFormation console at [https://console.amazonaws.cn/cloudformation](https://console.amazonaws.cn/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 Amazon CloudFormation can create IAM resources in your account.

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

Amazon CloudFormation provisions the resources specified in the template. It can take a few minutes to finish provisioning your resources. When the status of your Amazon 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 Amazon 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 Amazon CloudFormation template has populated some of the integration request fields. 
   +  The integration type is Amazon Web Services service. 
   +  The Amazon Web Services 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`. Amazon 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 Amazon 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.amazonaws.cn/dynamodb/](https://console.amazonaws.cn/dynamodb/) to verify that the example item is in your table. 

**To delete an Amazon CloudFormation stack**

1. Open the Amazon CloudFormation console at [https://console.amazonaws.cn/cloudformation](https://console.amazonaws.cn/cloudformation/).

1. Select your Amazon CloudFormation stack.

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

## Set up data transformation using the Amazon CLI


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 Amazon CloudFormation stack**

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

To complete the following tutorial, you need the [Amazon Command Line Interface (Amazon CLI) version 2](https://docs.amazonaws.cn/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 Amazon 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. Amazon 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 Amazon CloudFormation stack.

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

1. When the status of your Amazon 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 Amazon CloudFormation stack.

1.  Use the following command to create an Amazon Web Services 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-west-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 Amazon CloudFormation stack**
+ Use the following command to delete your Amazon CloudFormation resources.

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

## Completed data transformation Amazon CloudFormation template


The following example is a completed Amazon 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 Amazon CloudFormation template


```
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
Examples using variables for mapping template transformations

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


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-cn: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


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


 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


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


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

# Variables for data transformations for API Gateway
Variables for data transformations

When you create a parameter mapping, you can use context variables as your data source. When you create mapping template transformations, you can use context variables, input, and util variables in scripts you write in [Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html). For example mapping templates that use these reference variables, see [Examples using variables for mapping template transformations for API Gateway](api-gateway-mapping-variable-examples.md).

For a list of reference variables for access logging, see [Variables for access logging for API Gateway](api-gateway-variables-for-access-logging.md).

## Context variables for data transformations


You can use the following case-sensitive `$context` variables for data transformations.


| Parameter | Description | 
| --- | --- | 
| \$1context.accountId |  The API owner's Amazon account ID.  | 
| \$1context.apiId |  The identifier API Gateway assigns to your API.  | 
| \$1context.authorizer.claims.property |  A property of the claims returned from the Amazon Cognito user pool after the method caller is successfully authenticated. For more information, see [Control access to REST APIs using Amazon Cognito user pools as an authorizer](apigateway-integrate-with-cognito.md).  Calling `$context.authorizer.claims` returns null.   | 
| \$1context.authorizer.principalId |  The principal user identification associated with the token sent by the client and returned from an API Gateway Lambda authorizer (formerly known as a custom authorizer). For more information, see [Use API Gateway Lambda authorizers](apigateway-use-lambda-authorizer.md).  | 
| \$1context.authorizer.property |  The stringified value of the specified key-value pair of the `context` map returned from an API Gateway Lambda authorizer function. For example, if the authorizer returns the following `context` map:  <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> Calling `$context.authorizer.key` returns the `"value"` string, calling `$context.authorizer.numKey` returns the `"1"` string, and calling `$context.authorizer.boolKey` returns the `"true"` string. For *property*, the only supported special character is the underscore `(_)` character. For more information, see [Use API Gateway Lambda authorizers](apigateway-use-lambda-authorizer.md).  | 
| \$1context.awsEndpointRequestId |  The Amazon endpoint's request ID.  | 
| \$1context.deploymentId | The ID of the API deployment. | 
| \$1context.domainName |  The full domain name used to invoke the API. This should be the same as the incoming `Host` header.  | 
| \$1context.domainPrefix |  The first label of the `$context.domainName`.  | 
| \$1context.error.message |  A string containing an API Gateway error message. This variable can only be used for simple variable substitution in a [GatewayResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html) body-mapping template, which is not processed by the Velocity Template Language engine, and in access logging. For more information, see [Monitor WebSocket API execution with CloudWatch metrics](apigateway-websocket-api-logging.md) and [Setting up gateway responses to customize error responses](api-gateway-gatewayResponse-definition.md#customize-gateway-responses).  | 
| \$1context.error.messageString | The quoted value of \$1context.error.message, namely "\$1context.error.message". | 
| \$1context.error.responseType |  A [type](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html#responseType) of [GatewayResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html). This variable can only be used for simple variable substitution in a [GatewayResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html) body-mapping template, which is not processed by the Velocity Template Language engine, and in access logging. For more information, see [Monitor WebSocket API execution with CloudWatch metrics](apigateway-websocket-api-logging.md) and [Setting up gateway responses to customize error responses](api-gateway-gatewayResponse-definition.md#customize-gateway-responses).  | 
| \$1context.error.validationErrorString |  A string containing a detailed validation error message.  | 
| \$1context.extendedRequestId | The extended ID that API Gateway generates and assigns to the API request. The extended request ID contains useful information for debugging and troubleshooting. | 
| \$1context.httpMethod |  The HTTP method used. Valid values include: `DELETE`, `GET`, `HEAD`, `OPTIONS`, `PATCH`, `POST`, and `PUT`.  | 
| \$1context.identity.accountId |  The Amazon account ID associated with the request.  | 
| \$1context.identity.apiKey |  For API methods that require an API key, this variable is the API key associated with the method request. For methods that don't require an API key, this variable is null. For more information, see [Usage plans and API keys for REST APIs in API Gateway](api-gateway-api-usage-plans.md).  | 
| \$1context.identity.apiKeyId | The API key ID associated with an API request that requires an API key. | 
| \$1context.identity.caller |  The principal identifier of the caller that signed the request. Supported for resources that use IAM authorization.  | 
| \$1context.identity.cognitoAuthenticationProvider |  A comma-separated list of all the Amazon Cognito authentication providers used by the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  For example, for an identity from an Amazon Cognito user pool, `cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` For information about the available Amazon Cognito authentication providers, see [Using Federated Identities](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-identity.html) in the *Amazon Cognito Developer Guide*. | 
| \$1context.identity.cognitoAuthenticationType |  The Amazon Cognito authentication type of the caller making the request. Available only if the request was signed with Amazon Cognito credentials. Possible values include `authenticated` for authenticated identities and `unauthenticated` for unauthenticated identities. | 
| \$1context.identity.cognitoIdentityId |  The Amazon Cognito identity ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  | 
| \$1context.identity.cognitoIdentityPoolId |  The Amazon Cognito identity pool ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  | 
| \$1context.identity.principalOrgId |  The [Amazon organization ID](https://docs.amazonaws.cn/organizations/latest/userguide/orgs_manage_org_details.html).  | 
| \$1context.identity.sourceIp |  The source IP address of the immediate TCP connection making the request to the API Gateway endpoint.  | 
| \$1context.identity.clientCert.clientCertPem |  The PEM-encoded client certificate that the client presented during mutual TLS authentication. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled. Present only in access logs if mutual TLS authentication fails.  | 
| \$1context.identity.clientCert.subjectDN |  The distinguished name of the subject of the certificate that a client presents. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled. Present only in access logs if mutual TLS authentication fails.  | 
| \$1context.identity.clientCert.issuerDN |  The distinguished name of the issuer of the certificate that a client presents. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled. Present only in access logs if mutual TLS authentication fails.  | 
| \$1context.identity.clientCert.serialNumber |  The serial number of the certificate. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled. Present only in access logs if mutual TLS authentication fails.  | 
| \$1context.identity.clientCert.validity.notBefore |  The date before which the certificate is invalid. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled. Present only in access logs if mutual TLS authentication fails.  | 
| \$1context.identity.clientCert.validity.notAfter |  The date after which the certificate is invalid. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled. Present only in access logs if mutual TLS authentication fails.  | 
|  \$1context.identity.vpcId | The VPC ID of the VPC making the request to the API Gateway endpoint. | 
|  \$1context.identity.vpceId |  The VPC endpoint ID of the VPC endpoint making the request to the API Gateway endpoint. Present only when you have a private API.  | 
| \$1context.identity.user |  The principal identifier of the user that will be authorized against resource access. Supported for resources that use IAM authorization.  | 
| \$1context.identity.userAgent |  The [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) header of the API caller.  | 
| \$1context.identity.userArn |  The Amazon Resource Name (ARN) of the effective user identified after authentication. For more information, see [https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html).  | 
| \$1context.isCanaryRequest |  Returns `true` if the request was directed to the canary and `false` if the request was not directed to the canary. Present only when you have a canary enabled. | 
| \$1context.path | The request path. For example, for a non-proxy request URL of https://\$1rest-api-id\$1.execute-api.\$1region\$1.amazonaws.com/\$1stage\$1/root/child, the \$1context.path value is /\$1stage\$1/root/child.  | 
| \$1context.protocol | The request protocol, for example, HTTP/1.1.  API Gateway APIs can accept HTTP/2 requests, but API Gateway sends requests to backend integrations using HTTP/1.1. As a result, the request protocol is logged as HTTP/1.1 even if a client sends a request that uses HTTP/2.   | 
| \$1context.requestId |  An ID for the request. Clients can override this request ID. Use `$context.extendedRequestId` for a unique request ID that API Gateway generates.  | 
| \$1context.requestOverride.header.header\$1name |  The request header override. If this parameter is defined, it contains the headers to be used instead of the **HTTP Headers** that are defined in the **Integration Request** pane. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md).  | 
| \$1context.requestOverride.path.path\$1name |  The request path override. If this parameter is defined, it contains the request path to be used instead of the **URL Path Parameters** that are defined in the **Integration Request** pane. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md).  | 
| \$1context.requestOverride.querystring.querystring\$1name |  The request query string override. If this parameter is defined, it contains the request query strings to be used instead of the **URL Query String Parameters** that are defined in the **Integration Request** pane. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md).  | 
| \$1context.responseOverride.header.header\$1name | The response header override. If this parameter is defined, it contains the header to be returned instead of the Response header that is defined as the Default mapping in the Integration Response pane. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md). | 
| \$1context.responseOverride.status | The response status code override. If this parameter is defined, it contains the status code to be returned instead of the Method response status that is defined as the Default mapping in the Integration Response pane. For more information, see [Override your API's request and response parameters and status codes for REST APIs in API Gateway](apigateway-override-request-response-parameters.md). | 
| \$1context.requestTime | The [CLF](https://httpd.apache.org/docs/current/logs.html#common)-formatted request time (dd/MMM/yyyy:HH:mm:ss \$1-hhmm). | 
| \$1context.requestTimeEpoch | The [Epoch](https://en.wikipedia.org/wiki/Unix_time)-formatted request time, in milliseconds. | 
| \$1context.resourceId |  The identifier that API Gateway assigns to your resource.  | 
| \$1context.resourcePath |  The path to your resource. For example, for the non-proxy request URI of `https://{rest-api-id}.execute-api.{region}.amazonaws.com/{stage}/root/child`, The `$context.resourcePath` value is `/root/child`. For more information, see [Tutorial: Create a REST API with an HTTP non-proxy integration](api-gateway-create-api-step-by-step.md).   | 
| \$1context.stage |  The deployment stage of the API request (for example, `Beta` or `Prod`).  | 
| \$1context.wafResponseCode |  The response received from [Amazon WAF](https://docs.amazonaws.cn/waf/latest/developerguide/waf-chapter.html): `WAF_ALLOW` or `WAF_BLOCK`. Will not be set if the stage is not associated with a web ACL. For more information, see [Use Amazon WAF to protect your REST APIs in API Gateway](apigateway-control-access-aws-waf.md).  | 
| \$1context.webaclArn |  The complete ARN of the web ACL that is used to decide whether to allow or block the request. Will not be set if the stage is not associated with a web ACL. For more information, see [Use Amazon WAF to protect your REST APIs in API Gateway](apigateway-control-access-aws-waf.md).  | 

## Input variables


You can use the following case-sensitive `$input` variables to refer to the method request payload and method request parameters. The following functions are available:


| Variable and function | Description | 
| --- | --- | 
| \$1input.body |  Returns the raw request payload as a string. You can use `$input.body` to preserve entire floating point numbers, such as `10.00`. | 
| \$1input.json(x) | This function evaluates a JSONPath expression and returns the results as a JSON string. For example, `$input.json('$.pets')` returns a JSON string representing the `pets` structure. For more information about JSONPath, see [JSONPath](https://goessner.net/articles/JsonPath/) or [JSONPath for Java](https://github.com/json-path/JsonPath). | 
| \$1input.params() |  Returns a map of all the request parameters. We recommend that you use `$util.escapeJavaScript` to sanitize the result to avoid a potential injection attack. For full control of request sanitization, use a proxy integration without a template and handle request sanitization in your integration. | 
| \$1input.params(x) | Returns the value of a method request parameter from the path, query string, or header value (searched in that order), given a parameter name string `x`. We recommend that you use `$util.escapeJavaScript` to sanitize the parameter to avoid a potential injection attack. For full control of parameter sanitization, use a proxy integration without a template and handle request sanitization in your integration. | 
| \$1input.path(x) | Takes a JSONPath expression string (`x`) and returns a JSON object representation of the result. This allows you to access and manipulate elements of the payload natively in [Apache Velocity Template Language (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html). For example, if the expression `$input.path('$.pets')` returns an object like this: <pre>[<br />  { <br />    "id": 1, <br />    "type": "dog", <br />    "price": 249.99 <br />  }, <br />  { <br />    "id": 2, <br />    "type": "cat", <br />    "price": 124.99 <br />  }, <br />  { <br />    "id": 3, <br />    "type": "fish", <br />    "price": 0.99 <br />  } <br />]</pre> `$input.path('$.pets').size()` would return `"3"`. For more information about JSONPath, see [JSONPath](https://goessner.net/articles/JsonPath/) or [JSONPath for Java](https://github.com/json-path/JsonPath). | 

## Stage variables


You can use the following stage variables as placeholders for ARNs and URLs in method integrations. For more information, see [Use stage variables for a REST API in API Gateway](stage-variables.md).


| Syntax | Description | 
| --- | --- | 
| \$1stageVariables.variable\$1name, \$1stageVariables['variable\$1name'], or \$1\$1stageVariables['variable\$1name']\$1  |  *variable\$1name* represents a stage variable name.  | 

## Util variables


You can use the following case-sensitive `$util` variables to use utility functions for mapping templates. Unless otherwise specified, the default character set is UTF-8.


| Function | Description | 
| --- | --- | 
| \$1util.escapeJavaScript() |  Escapes the characters in a string using JavaScript string rules.  This function will turn any regular single quotes (`'`) into escaped ones (`\'`). However, the escaped single quotes are not valid in JSON. Thus, when the output from this function is used in a JSON property, you must turn any escaped single quotes (`\'`) back to regular single quotes (`'`). This is shown in the following example:  <pre> "input" : "$util.escapeJavaScript(data).replaceAll("\\'","'")"</pre>   | 
| \$1util.parseJson() |   Takes "stringified" JSON and returns an object representation of the result. You can use the result from this function to access and manipulate elements of the payload natively in Apache Velocity Template Language (VTL). For example, if you have the following payload:  <pre>{"errorMessage":"{\"key1\":\"var1\",\"key2\":{\"arr\":[1,2,3]}}"}</pre>  and use the following mapping template  <pre>#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))<br />{<br />   "errorMessageObjKey2ArrVal" : $errorMessageObj.key2.arr[0]<br />}<br /></pre> You will get the following output: <pre>{<br />   "errorMessageObjKey2ArrVal" : 1<br />}<br /></pre>  | 
| \$1util.urlEncode() | Converts a string into "application/x-www-form-urlencoded" format. | 
| \$1util.urlDecode() | Decodes an "application/x-www-form-urlencoded" string. | 
| \$1util.base64Encode() | Encodes the data into a base64-encoded string. | 
| \$1util.base64Decode() | Decodes the data from a base64-encoded string. | 

# Gateway responses for REST APIs in API Gateway
Gateway responses

 A gateway response is identified by a response type that is defined by API Gateway. The response consists of an HTTP status code, a set of additional headers that are specified by parameter mappings, and a payload that is generated by a non-[VTL](https://velocity.apache.org/engine/devel/vtl-reference.html) mapping template. 

 In the API Gateway REST API, a gateway response is represented by the [GatewayResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html). In OpenAPI, a `GatewayResponse` instance is described by the [x-amazon-apigateway-gateway-responses.gatewayResponse](api-gateway-swagger-extensions-gateway-responses.gatewayResponse.md) extension. 

To enable a gateway response, you set up a gateway response for a [supported response type](supported-gateway-response-types.md) at the API level. Whenever API Gateway returns a response of this type, the header mappings and payload mapping templates defined in the gateway response are applied to return the mapped results to the API caller. 

 In the following section, we show how to set up gateway responses by using the API Gateway console and the API Gateway REST API. 

## Setting up gateway responses to customize error responses


If API Gateway fails to process an incoming request, it returns to the client an error response without forwarding the request to the integration backend. By default, the error response contains a short descriptive error message. For example, if you attempt to call an operation on an undefined API resource, you receive an error response with the `{ "message": "Missing Authentication Token" }` message. If you are new to API Gateway, you may find it difficult to understand what actually went wrong. 

 For some of the error responses, API Gateway allows customization by API developers to return the responses in different formats. For the `Missing Authentication Token` example, you can add a hint to the original response payload with the possible cause, as in this example: `{"message":"Missing Authentication Token", "hint":"The HTTP method or resources may not be supported."}`. 

 When your API mediates between an external exchange and the Amazon Cloud, you use VTL mapping templates for integration request or integration response to map the payload from one format to another. However, the VTL mapping templates work only for valid requests with successful responses. 

For invalid requests, API Gateway bypasses the integration altogether and returns an error response. You must use the customization to render the error responses in an exchange-compliant format. Here, the customization is rendered in a non-VTL mapping template supporting only simple variable substitutions. 

 Generalizing the API Gateway-generated error response to any responses generated by API Gateway, we refer to them as *gateway responses*. This distinguishes API Gateway-generated responses from the integration responses. A gateway response mapping template can access `$context` variable values and `$stageVariables` property values, as well as method request parameters, in the form of `method.request.param-position.param-name`. 

For more information about `$context` variables, see [Context variables for data transformations](api-gateway-mapping-template-reference.md#context-variable-reference). For more information about `$stageVariables`, see [Stage variables](api-gateway-mapping-template-reference.md#stagevariables-template-reference). For more information about method request parameters, see [Input variables](api-gateway-mapping-template-reference.md#input-variable-reference).

**Topics**
+ [

## Setting up gateway responses to customize error responses
](#customize-gateway-responses)
+ [

# Set up a gateway response for a REST API using the API Gateway console
](set-up-gateway-response-using-the-console.md)
+ [

# Set up a gateway response using the API Gateway REST API
](set-up-gateway-response-using-the-api.md)
+ [

# Set up gateway response customization in OpenAPI
](set-up-gateway-responses-in-swagger.md)
+ [

# Gateway response types for API Gateway
](supported-gateway-response-types.md)

# Set up a gateway response for a REST API using the API Gateway console


The following example shows how to set up a gateway response for a REST API using the API Gateway console 

**To customize a gateway response using the API Gateway console**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. In the main navigation pane, choose **Gateway responses**.

1. Choose a response type, and then choose **Edit**. In this walkthrough, we use **Missing authentication token** as an example. 

1. You can change the API Gateway-generated **Status code** to return a different status code that meets your API's requirements. In this example, the customization changes the status code from the default (`403`) to `404` because this error message occurs when a client calls an unsupported or invalid resource that can be thought of as not found.

1. To return custom headers, choose **Add response header** under **Response headers**. For illustration purposes, we add the following custom headers: 

   ```
   Access-Control-Allow-Origin:'a.b.c'
   x-request-id:method.request.header.x-amzn-RequestId
   x-request-path:method.request.path.petId
   x-request-query:method.request.querystring.q
   ```

   In the preceding header mappings, a static domain name (`'a.b.c'`) is mapped to the `Allow-Control-Allow-Origin` header to allow CORS access to the API; the input request header of `x-amzn-RequestId` is mapped to `request-id` in the response; the `petId` path variable of the incoming request is mapped to the `request-path` header in the response; and the `q` query parameter of the original request is mapped to the `request-query` header of the response.

1. Under **Response templates**, keep `application/json` for **Content Type** and enter the following body mapping template in the **Template body** editor:

   ```
   {
        "message":"$context.error.messageString",
        "type": "$context.error.responseType",
        "statusCode": "'404'",
        "stage": "$context.stage",
        "resourcePath": "$context.resourcePath",
        "stageVariables.a": "$stageVariables.a"
   }
   ```

   This example shows how to map `$context` and `$stageVariables` properties to properties of the gateway response body.

1. Choose **Save changes**.

1. Deploy the API to a new or existing stage.

Test your gateway response by calling the following CURL command, assuming the corresponding API method's invoke URL is `https://o81lxisefl.execute-api.us-east-1.amazonaws.com/custErr/pets/{petId}`:

```
curl -v -H 'x-amzn-RequestId:123344566' https://o81lxisefl.execute-api.us-east-1.amazonaws.com/custErr/pets/5/type?q=1
```

Because the extra query string parameter `q=1` isn't compatible with the API, an error is returned from the specified gateway response. You should get a gateway response similar to the following:

```
> GET /custErr/pets/5?q=1 HTTP/1.1
Host: o81lxisefl.execute-api.us-east-1.amazonaws.com
User-Agent: curl/7.51.0
Accept: */*
 
HTTP/1.1 404 Not Found
Content-Type: application/json
Content-Length: 334
Connection: keep-alive
Date: Tue, 02 May 2017 03:15:47 GMT
x-amzn-RequestId: 123344566
Access-Control-Allow-Origin: a.b.c
x-amzn-ErrorType: MissingAuthenticationTokenException
header-1: static
x-request-query: 1
x-request-path: 5
X-Cache: Error from cloudfront
Via: 1.1 441811a054e8d055b893175754efd0c3.cloudfront.net (CloudFront)
X-Amz-Cf-Id: nNDR-fX4csbRoAgtQJ16u0rTDz9FZWT-Mk93KgoxnfzDlTUh3flmzA==
 
{
     "message":"Missing Authentication Token",
     "type": MISSING_AUTHENTICATION_TOKEN,
     "statusCode": '404',
     "stage": custErr,
     "resourcePath": /pets/{petId},
     "stageVariables.a": a
}
```

The preceding example assumes that the API backend is [Pet Store](http://petstore-demo-endpoint.execute-api.com/petstore/pets) and the API has a stage variable, `a`, defined.

# Set up a gateway response using the API Gateway REST API


 Before customizing a gateway response using the API Gateway REST API, you must have already created an API and have obtained its identifier. To retrieve the API identifier, you can follow [restapi:gateway-responses](https://docs.amazonaws.cn/apigateway/latest/api/API_GetGatewayResponses.html) link relation and examine the result. 

**To customize a gateway response using the API Gateway REST API**

1. To overwrite an entire [GatewayResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html) instance, call the [gatewayresponse:put](https://docs.amazonaws.cn/apigateway/latest/api/API_PutGatewayResponse.html) action. Specify a desired [responseType](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html#responseType) in the URL path parameter, and supply in the request payload the [statusCode](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html#statusCode), [responseParameters](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html#responseParameters), and [responseTemplates](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html#responseTemplates) mappings.

1. To update part of a `GatewayResponse` instance, call the [gatewayresponse:update](https://docs.amazonaws.cn/apigateway/latest/api/API_UpdateGatewayResponse.html) action. Specify a desired `responseType` in the URL path parameter, and supply in the request payload the individual `GatewayResponse` properties you want—for example, the `responseParameters` or the `responseTemplates` mapping.

# Set up gateway response customization in OpenAPI


 You can use the `x-amazon-apigateway-gateway-responses` extension at the API root level to customize gateway responses in OpenAPI. The following OpenAPI definition shows an example for customizing the [GatewayResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_GatewayResponse.html) of the `MISSING_AUTHENTICATION_TOKEN` type. 

```
  "x-amazon-apigateway-gateway-responses": {
    "MISSING_AUTHENTICATION_TOKEN": {
      "statusCode": 404,
      "responseParameters": {
        "gatewayresponse.header.x-request-path": "method.input.params.petId",
        "gatewayresponse.header.x-request-query": "method.input.params.q",
        "gatewayresponse.header.Access-Control-Allow-Origin": "'a.b.c'",
        "gatewayresponse.header.x-request-header": "method.input.params.Accept"
      },
      "responseTemplates": {
        "application/json": "{\n     \"message\": $context.error.messageString,\n     \"type\":  \"$context.error.responseType\",\n     \"stage\":  \"$context.stage\",\n     \"resourcePath\":  \"$context.resourcePath\",\n     \"stageVariables.a\":  \"$stageVariables.a\",\n     \"statusCode\": \"'404'\"\n}"
      }
    }
```

In this example, the customization changes the status code from the default (`403`) to `404`. It also adds to the gateway response four header parameters and one body mapping template for the `application/json` media type.

# Gateway response types for API Gateway


 API Gateway exposes the following gateway responses for customization by API developers. 


| Gateway response type | Default status code | Description | 
| --- | --- | --- | 
| ACCESS\$1DENIED | 403 | The gateway response for authorization failure—for example, when access is denied by a custom or Amazon Cognito authorizer. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| API\$1CONFIGURATION\$1ERROR | 500 | The gateway response for an invalid API configuration—including when an invalid endpoint address is submitted, when base64 decoding fails on binary data when binary support is enacted, or when integration response mapping can't match any template and no default template is configured. If the response type is unspecified, this response defaults to the `DEFAULT_5XX` type. | 
| AUTHORIZER\$1CONFIGURATION\$1ERROR | 500 | The gateway response for failing to connect to a custom or Amazon Cognito authorizer. If the response type is unspecified, this response defaults to the `DEFAULT_5XX` type. | 
| AUTHORIZER\$1FAILURE | 500 | The gateway response when a custom or Amazon Cognito authorizer failed to authenticate the caller. If the response type is unspecified, this response defaults to the `DEFAULT_5XX` type. | 
| BAD\$1REQUEST\$1PARAMETERS | 400 | The gateway response when the request parameter cannot be validated according to an enabled request validator. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| BAD\$1REQUEST\$1BODY | 400 | The gateway response when the request body cannot be validated according to an enabled request validator. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| DEFAULT\$14XX |  Null | The default gateway response for an unspecified response type with the status code of `4XX`. Changing the status code of this fallback gateway response changes the status codes of all other `4XX` responses to the new value. Resetting this status code to null reverts the status codes of all other `4XX` responses to their original values.  [Amazon WAF custom responses](https://docs.amazonaws.cn/waf/latest/developerguide/waf-custom-request-response.html) take precedence over custom gateway responses.   | 
| DEFAULT\$15XX | Null | The default gateway response for an unspecified response type with a status code of `5XX`. Changing the status code of this fallback gateway response changes the status codes of all other `5XX` responses to the new value. Resetting this status code to null reverts the status codes of all other `5XX` responses to their original values. | 
| EXPIRED\$1TOKEN | 403 | The gateway response for an Amazon authentication token expired error. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| INTEGRATION\$1FAILURE | 504 | The gateway response for an integration failed error. If the response type is unspecified, this response defaults to the `DEFAULT_5XX` type. | 
| INTEGRATION\$1TIMEOUT | 504 | The gateway response for an integration timed out error. If the response type is unspecified, this response defaults to the `DEFAULT_5XX` type. | 
| INVALID\$1API\$1KEY | 403 | The gateway response for an invalid API key submitted for a method requiring an API key. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type.  | 
| INVALID\$1SIGNATURE | 403 | The gateway response for an invalid Amazon signature error. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| MISSING\$1AUTHENTICATION\$1TOKEN | 403 | The gateway response for a missing authentication token error, including the cases when the client attempts to invoke an unsupported API method or resource. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| QUOTA\$1EXCEEDED | 429 | The gateway response for the usage plan quota exceeded error. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| REQUEST\$1TOO\$1LARGE | 413 | The gateway response for the request too large error. If the response type is unspecified, this response defaults to: `HTTP content length exceeded 10485760 bytes`. | 
| RESOURCE\$1NOT\$1FOUND | 404 | The gateway response when API Gateway cannot find the specified resource after an API request passes authentication and authorization, except for API key authentication and authorization. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| THROTTLED | 429 | The gateway response when usage plan-, method-, stage-, or account-level throttling limits exceeded. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| UNAUTHORIZED | 401 | The gateway response when the custom or Amazon Cognito authorizer failed to authenticate the caller. | 
| UNSUPPORTED\$1MEDIA\$1TYPE | 415 | The gateway response when a payload is of an unsupported media type, if strict passthrough behavior is enabled. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type. | 
| WAF\$1FILTERED | 403 | The gateway response when a request is blocked by Amazon WAF. If the response type is unspecified, this response defaults to the `DEFAULT_4XX` type.  [Amazon WAF custom responses](https://docs.amazonaws.cn/waf/latest/developerguide/waf-custom-request-response.html) take precedence over custom gateway responses.   | 

# CORS for REST APIs in API Gateway
CORS

[Cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a browser security feature that restricts cross-origin HTTP requests that are initiated from scripts running in the browser. For more information, see [What is CORS?](http://www.amazonaws.cn/what-is/cross-origin-resource-sharing/).

## Determining whether to enable CORS support


A *cross-origin* HTTP request is one that is made to:
+ A different *domain* (for example, from `example.com` to `amazondomains.com`)
+ A different *subdomain* (for example, from `example.com` to `petstore.example.com`)
+ A different *port* (for example, from `example.com` to `example.com:10777`)
+ A different *protocol* (for example, from `https://example.com` to `http://example.com`)

 If you cannot access your API and receive an error message that contains `Cross-Origin Request Blocked`, you might need to enable CORS.

Cross-origin HTTP requests can be divided into two types: *simple* requests and *non-simple* requests.

## Enabling CORS for a simple request


An HTTP request is *simple* if all of the following conditions are true:
+ It is issued against an API resource that allows only `GET`, `HEAD`, and `POST` requests.
+ If it is a `POST` method request, it must include an `Origin` header.
+ The request payload content type is `text/plain`, `multipart/form-data`, or `application/x-www-form-urlencoded`.
+ The request does not contain custom headers.
+ Any additional requirements that are listed in the [Mozilla CORS documentation for simple requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests).

For simple cross-origin `POST` method requests, the response from your resource needs to include the header `Access-Control-Allow-Origin: '*'` or `Access-Control-Allow-Origin:'origin'`.

All other cross-origin HTTP requests are *non-simple* requests.

## Enabling CORS for a non-simple request


If your API's resources receive non-simple requests, you must enable additional CORS support depending on your integration type.

### Enabling CORS for non-proxy integrations


For these integrations, the [CORS protocol](https://fetch.spec.whatwg.org/#http-cors-protocol) requires the browser to send a preflight request to the server and wait for approval (or a request for credentials) from the server before sending the actual request. You must configure your API to send an appropriate response to the preflight request. 

 To create a preflight response: 

1. Create an `OPTIONS` method with a mock integration.

1. Add the following response headers to the 200 method response:
   + `Access-Control-Allow-Headers`
   + `Access-Control-Allow-Methods`
   + `Access-Control-Allow-Origin`

1. Set the integration passthrough behavior to `NEVER`. In this case, the method request of an unmapped content type will be rejected with an HTTP 415 Unsupported Media Type response. For more information, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md).

1. Enter values for the response headers. To allow all origins, all methods, and common headers, use the following header values:
   + `Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'`
   + `Access-Control-Allow-Methods: 'DELETE,GET,HEAD,OPTIONS,PUT,POST,PATCH'`
   + `Access-Control-Allow-Origin: '*'`

After creating the preflight request, you must return the `Access-Control-Allow-Origin: '*'` or `Access-Control-Allow-Origin:'origin'` header for all CORS-enabled methods for at least all 200 responses.

### Enabling CORS for non-proxy integrations using the Amazon Web Services Management Console


You can use the Amazon Web Services Management Console to enable CORS. API Gateway creates an `OPTIONS` method and adds the `Access-Control-Allow-Origin` header to your existing method integration responses. This doesn’t always work, and sometimes you need to manually modify the integration response to return the `Access-Control-Allow-Origin` header for all CORS-enabled methods for at least all 200 responses.

If you have binary media types set to `*/*` for your API, when API Gateway creates an `OPTIONS` method, change the `contentHandling` to `CONVERT_TO_TEXT`.

The following [update-integration](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-integration.html) command changes the `contentHandling` to `CONVERT_TO_TEXT` for an integration request: 

```
aws apigateway update-integration \
  --rest-api-id abc123 \
  --resource-id aaa111 \
  --http-method OPTIONS \
  --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
```

The following [update-integration-response](https://docs.amazonaws.cn/cli/latest/reference/apigateway/update-integration-response.html) command changes the `contentHandling` to `CONVERT_TO_TEXT` for an integration response:

```
aws apigateway update-integration-response \
  --rest-api-id abc123 \
  --resource-id aaa111 \
  --http-method OPTIONS \
  --status-code 200 \
  --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
```

## Enabling CORS support for proxy integrations


For a Lambda proxy integration or HTTP proxy integration, your backend is responsible for returning the `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, and `Access-Control-Allow-Headers` headers, because a proxy integration doesn't return an integration response. 

The following example Lambda functions return the required CORS headers:

------
#### [ Node.js ]

```
export const handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Headers" : "Content-Type",
            "Access-Control-Allow-Origin": "https://www.example.com",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
        },
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

------
#### [ Python 3 ]

```
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Allow-Origin': 'https://www.example.com',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        },
        'body': json.dumps('Hello from Lambda!')
    }
```

------

**Topics**
+ [

## Determining whether to enable CORS support
](#apigateway-cors-request-types)
+ [

## Enabling CORS for a simple request
](#apigateway-cors-simple-request)
+ [

## Enabling CORS for a non-simple request
](#apigateway-enable-cors-non-simple)
+ [

## Enabling CORS support for proxy integrations
](#apigateway-enable-cors-proxy)
+ [

# Enable CORS on a resource using the API Gateway console
](how-to-cors-console.md)
+ [

# Enable CORS on a resource using the API Gateway import API
](enable-cors-for-resource-using-swagger-importer-tool.md)
+ [

# Test CORS for an API Gateway API
](apigateway-test-cors.md)

# Enable CORS on a resource using the API Gateway console
Enable CORS using the console

You can use the API Gateway console to enable CORS support for one or all methods on a REST API resource that you have created. After you enable COR support, set the integration passthrough behavior to `NEVER`. In this case, the method request of an unmapped content type will be rejected with an HTTP 415 Unsupported Media Type response. For more information, see [Method request behavior for payloads without mapping templates for REST APIs in API Gateway](integration-passthrough-behaviors.md)

**Important**  
Resources can contain child resources. Enabling CORS support for a resource and its methods does not recursively enable it for child resources and their methods.

**To enable CORS support on a REST API resource**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose an API. 

1. Choose a resource under **Resources**.

1. In the **Resource details** section, choose **Enable CORS**.

    

1.  In the **Enable CORS** box, do the following: 

   1. (Optional) If you created a custom gateway response and want to enable CORS support for a response, select a gateway response.

   1. Select each method to enable CORS support. The `OPTION` method must have CORS enabled. 

      If you enable CORS support for an `ANY` method, CORS is enabled for all methods.

   1.  In the **Access-Control-Allow-Headers** input field, enter a static string of a comma-separated list of headers that the client must submit in the actual request of the resource. Use the console-provided header list of `'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'` or specify your own headers. 

   1. Use the console-provided value of `'*'` as the **Access-Control-Allow-Origin** header value to allow access requests from all origins, or specify an origin to be permitted to access the resource. 

   1. Choose **Save**.
**Important**  
 When applying the above instructions to the `ANY` method in a proxy integration, any applicable CORS headers will not be set. Instead, your backend must return the applicable CORS headers, such as `Access-Control-Allow-Origin`. 

After CORS is enabled on the `GET` method, an `OPTIONS` method is added to the resource, if it is not already there. The `200` response of the `OPTIONS` method is automatically configured to return the three `Access-Control-Allow-*` headers to fulfill preflight handshakes. In addition, the actual (`GET`) method is also configured by default to return the `Access-Control-Allow-Origin` header in its 200 response as well. For other types of responses, you will need to manually configure them to return `Access-Control-Allow-Origin'` header with '\$1' or specific origins, if you do not want to return the `Cross-origin access` error.

After you enable CORS support on your resource, you must deploy or redeploy the API for the new settings to take effect. For more information, see [Create a deployment](set-up-deployments.md#create-deployment).

**Note**  
If you cannot enable CORS support on your resource after following the procedure, we recommend that you compare your CORS configuration to the example API `/pets` resource. To learn how to create the example API, see [Tutorial: Create a REST API by importing an example](api-gateway-create-api-from-example.md).

# Enable CORS on a resource using the API Gateway import API
Enable CORS using OpenAPI definition

If you are using the [API Gateway Import API](api-gateway-import-api.md), you can set up CORS support using an OpenAPI file. You must first define an `OPTIONS` method in your resource that returns the required headers.

**Note**  
Web browsers expect Access-Control-Allow-Headers, and Access-Control-Allow-Origin headers to be set up in each API method that accepts CORS requests. In addition, some browsers first make an HTTP request to an `OPTIONS` method in the same resource, and then expect to receive the same headers.

## Example `Options` method


The following example creates an `OPTIONS` method for a mock integration.

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

```
/users:
  options:
    summary: CORS support
    description: |
      Enable CORS by returning correct headers
    tags:
    - CORS
    responses:
      200:
        description: Default response for CORS method
        headers:
          Access-Control-Allow-Origin:
            schema:
              type: "string"
          Access-Control-Allow-Methods:
            schema:
              type: "string"
          Access-Control-Allow-Headers:
            schema:
              type: "string"
        content: {}
    x-amazon-apigateway-integration:
      type: mock
      requestTemplates:
        application/json: "{\"statusCode\": 200}"
      passthroughBehavior: "never"
      responses:
        default:
          statusCode: "200"
          responseParameters:
            method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
            method.response.header.Access-Control-Allow-Methods: "'*'"
            method.response.header.Access-Control-Allow-Origin: "'*'"
```

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

```
/users: 
   options:
      summary: CORS support
      description: |
        Enable CORS by returning correct headers
      consumes:
        - "application/json"
      produces:
        - "application/json"
      tags:
        - CORS
      x-amazon-apigateway-integration:
        type: mock
        requestTemplates: "{\"statusCode\": 200}"
        passthroughBehavior: "never"
        responses:
          "default":
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Methods : "'*'"
              method.response.header.Access-Control-Allow-Origin : "'*'"
      responses:
        200:
          description: Default response for CORS method
          headers:
            Access-Control-Allow-Headers:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Origin:
              type: "string"
```

------

Once you have configured the `OPTIONS` method for your resource, you can add the required headers to the other methods in the same resource that need to accept CORS requests.

1. Declare the **Access-Control-Allow-Origin** and **Headers** to the response types.

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

   ```
       responses:
         200:
           description: Default response for CORS method
           headers:
             Access-Control-Allow-Origin:
               schema:
                 type: "string"
             Access-Control-Allow-Methods:
               schema:
                 type: "string"
             Access-Control-Allow-Headers:
               schema:
                 type: "string"
           content: {}
   ```

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

   ```
       responses:
           200:
             description: Default response for CORS method
             headers:
               Access-Control-Allow-Headers:
                 type: "string"
               Access-Control-Allow-Methods:
                 type: "string"
               Access-Control-Allow-Origin:
                 type: "string"
   ```

------

1. In the `x-amazon-apigateway-integration` tag, set up the mapping for those headers to your static values:

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

   ```
       responses:
           default:
             statusCode: "200"
             responseParameters:
               method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
               method.response.header.Access-Control-Allow-Methods: "'*'"
               method.response.header.Access-Control-Allow-Origin: "'*'"
             responseTemplates:
               application/json: |
                 {}
   ```

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

   ```
       responses:
             "default":
               statusCode: "200"
               responseParameters:
                 method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
                 method.response.header.Access-Control-Allow-Methods : "'*'"
                 method.response.header.Access-Control-Allow-Origin : "'*'"
   ```

------

## Example API


The following example creates a complete API with an `OPTIONS` method and a `GET` method with an `HTTP` integration.

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

```
openapi: "3.0.1"
info:
  title: "cors-api"
  description: "cors-api"
  version: "2024-01-16T18:36:01Z"
servers:
- url: "/{basePath}"
  variables:
    basePath:
      default: "/test"
paths:
  /:
    get:
      operationId: "GetPet"
      responses:
        "200":
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        httpMethod: "GET"
        uri: "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets"
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: "never"
        type: "http"
    options:
      responses:
        "200":
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Empty"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "never"
        type: "mock"
components:
  schemas:
    Empty:
      type: "object"
```

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

```
swagger: "2.0"
info:
  description: "cors-api"
  version: "2024-01-16T18:36:01Z"
  title: "cors-api"
basePath: "/test"
schemes:
- "https"
paths:
  /:
    get:
      operationId: "GetPet"
      produces:
      - "application/json"
      responses:
        "200":
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
      x-amazon-apigateway-integration:
        httpMethod: "GET"
        uri: "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets"
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: "never"
        type: "http"
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        "200":
          description: "200 response"
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Headers:
              type: "string"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "never"
        type: "mock"
definitions:
  Empty:
    type: "object"
```

------

# Test CORS for an API Gateway API


You can test your API's CORS configuration by invoking your API, and checking the CORS headers in the response. The following `curl` command sends an OPTIONS request to a deployed API. 

```
curl -v -X OPTIONS https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}
```

```
< HTTP/1.1 200 OK
< Date: Tue, 19 May 2020 00:55:22 GMT
< Content-Type: application/json
< Content-Length: 0
< Connection: keep-alive
< x-amzn-RequestId: a1b2c3d4-5678-90ab-cdef-abc123
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token
< x-amz-apigw-id: Abcd=
< Access-Control-Allow-Methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
```

The `Access-Control-Allow-Origin`, `Access-Control-Allow-Headers`, and `Access-Control-Allow-Methods` headers in the response show that the API supports CORS. For more information, see [CORS for REST APIs in API Gateway](how-to-cors.md).

# Binary media types for REST APIs in API Gateway
Binary media types

In API Gateway, the API request and response have a text or binary payload. A text payload is a `UTF-8`-encoded JSON string. A binary payload is anything other than a text payload. The binary payload can be, for example, a JPEG file, a GZip file, or an XML file. The API configuration required to support binary media depends on whether your API uses proxy or non-proxy integrations. 

If you use a proxy integration with payload response streaming, you don't need to configure your binary media types. For more information, see [Stream the integration response for your proxy integrations in API Gateway](response-transfer-mode.md).

## Amazon Lambda proxy integrations


To handle binary payloads for Amazon Lambda proxy integrations, you must base64-encode your function's response. You must also configure the [binaryMediaTypes](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html#apigw-Type-RestApi-binaryMediaTypes) for your API. Your API's `binaryMediaTypes` configuration is a list of content types that your API treats as binary data. Example binary media types include `image/png` or `application/octet-stream`. You can use the wildcard character (`*`) to cover multiple media types.

API Gateway uses the first `Accept` header from clients to determine if a response should return binary media. To return binary media when you can't control the order of `Accept` header values, such as requests from a browser, set your API's binary media types to `*/*`.

For example code, see [Return binary media from a Lambda proxy integration in API Gateway](lambda-proxy-binary-media.md).

If you use a Lambda proxy integration with payload response streaming, you don't need to configure your binary media types. For more information, see [Set up a Lambda proxy integration with payload response streaming in API Gateway](response-transfer-mode-lambda.md).

## Non-proxy integrations


To handle binary payloads for non-proxy integrations, you add the media types to the [binaryMediaTypes](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html#apigw-Type-RestApi-binaryMediaTypes) list of the `RestApi` resource. Your API's `binaryMediaTypes` configuration is a list of content types that your API treats as binary data. Alternatively, you can set the [contentHandling](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html#contentHandling) properties on the [Integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) and the [IntegrationResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resources. The `contentHandling` value can be `CONVERT_TO_BINARY`, `CONVERT_TO_TEXT`, or undefined. 

**Note**  
For `MOCK` or private integrations, setting the `contentHandling` properties isn't supported in the Amazon Web Services Management Console. You must use the Amazon CLI, Amazon CloudFormation, or an SDK to set the `contentHandling` properties.

Depending on the `contentHandling` value, and whether the `Content-Type` header of the response or the `Accept` header of the incoming request matches an entry in the `binaryMediaTypes` list, API Gateway can encode the raw binary bytes as a base64-encoded string, decode a base64-encoded string back to its raw bytes, or pass the body through without modification. 

You must configure the API as follows to support binary payloads for your API in API Gateway: 
+ Add the desired binary media types to the `binaryMediaTypes` list on the [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource. If this property and the `contentHandling` property are not defined, the payloads are handled as UTF-8 encoded JSON strings.
+ Address the `contentHandling` property of the [Integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource. 
  + To have the request payload converted from a base64-encoded string to its binary blob, set the property to `CONVERT_TO_BINARY`.
  + To have the request payload converted from a binary blob to a base64-encoded string, set the property to `CONVERT_TO_TEXT`.
  + To pass the payload through without modification, leave the property undefined. To pass a binary payload through without modification, you must also ensure that the `Content-Type` matches one of the `binaryMediaTypes` entries, and that [passthrough behaviors](integration-passthrough-behaviors.md) are enabled for the API. 
+ Set the `contentHandling` property of the [IntegrationResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resource. The `contentHandling` property, `Accept` header in client requests, and your API's `binaryMediaTypes` combined determine how API Gateway handles content type conversions. For details, see [Content type conversions in API Gateway](api-gateway-payload-encodings-workflow.md). 

**Important**  
When a request contains multiple media types in its `Accept` header, API Gateway honors only the first `Accept` media type. If you can't control the order of the `Accept` media types and the media type of your binary content isn't the first in the list, add the first `Accept` media type in the `binaryMediaTypes` list of your API. API Gateway handles all content types in this list as binary.   
For example, to send a JPEG file using an `<img>` element in a browser, the browser might send `Accept:image/webp,image/*,*/*;q=0.8` in a request. By adding `image/webp` to the `binaryMediaTypes` list, the endpoint receives the JPEG file as binary. 

For detailed information about how API Gateway handles the text and binary payloads, see [Content type conversions in API Gateway](api-gateway-payload-encodings-workflow.md).

# Content type conversions in API Gateway


 The combination of your API's `binaryMediaTypes`, the headers in client requests, and the integration `contentHandling` property determine how API Gateway encodes payloads.

The following table shows how API Gateway converts the request payload for specific configurations of a request's `Content-Type` header, the `binaryMediaTypes` list of a [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource, and the `contentHandling` property value of the [Integration](https://docs.amazonaws.cn/apigateway/latest/api/API_Integration.html) resource.


| Method request payload | Request `Content-Type` header | `binaryMediaTypes` | `contentHandling` | Integration request payload | 
| --- | --- | --- | --- | --- | 
| Text data | Any data type | Undefined | Undefined | UTF8-encoded string | 
| Text data | Any data type | Undefined | CONVERT\$1TO\$1BINARY | Base64-decoded binary blob | 
| Text data | Any data type | Undefined | CONVERT\$1TO\$1TEXT | UTF8-encoded string | 
| Text data | A text data type | Set with matching media types | Undefined | Text data | 
| Text data | A text data type | Set with matching media types | CONVERT\$1TO\$1BINARY | Base64-decoded binary blob | 
| Text data | A text data type | Set with matching media types | CONVERT\$1TO\$1TEXT | Text data | 
| Binary data | A binary data type | Set with matching media types | Undefined | Binary data | 
| Binary data | A binary data type | Set with matching media types | CONVERT\$1TO\$1BINARY | Binary data | 
| Binary data | A binary data type | Set with matching media types | CONVERT\$1TO\$1TEXT | Base64-encoded string | 

The following table shows how API Gateway converts the response payload for specific configurations of a request's `Accept` header, the `binaryMediaTypes` list of a [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource, and the `contentHandling` property value of the [IntegrationResponse](https://docs.amazonaws.cn/apigateway/latest/api/API_IntegrationResponse.html) resource.

**Important**  
 When a request contains multiple media types in its `Accept` header, API Gateway honors only the first `Accept` media type. If you can't control the order of the `Accept` media types and the media type of your binary content isn't the first in the list, add the first `Accept` media type in the `binaryMediaTypes` list of your API. API Gateway handles all content types in this list as binary.   
For example, to send a JPEG file using an `<img>` element in a browser, the browser might send `Accept:image/webp,image/*,*/*;q=0.8` in a request. By adding `image/webp` to the `binaryMediaTypes` list, the endpoint receives the JPEG file as binary. 


| Integration response payload | Request `Accept` header | `binaryMediaTypes` | `contentHandling` | Method response payload | 
| --- | --- | --- | --- | --- | 
| Text or binary data | A text type | Undefined | Undefined | UTF8-encoded string | 
| Text or binary data | A text type | Undefined | CONVERT\$1TO\$1BINARY | Base64-decoded blob | 
| Text or binary data | A text type | Undefined | CONVERT\$1TO\$1TEXT | UTF8-encoded string | 
| Text data | A text type | Set with matching media types | Undefined | Text data | 
| Text data | A text type | Set with matching media types | CONVERT\$1TO\$1BINARY | Base64-decoded blob | 
| Text data | A text type | Set with matching media types | CONVERT\$1TO\$1TEXT | UTF8-encoded string | 
| Text data | A binary type | Set with matching media types | Undefined | Base64-decoded blob | 
| Text data | A binary type | Set with matching media types | CONVERT\$1TO\$1BINARY | Base64-decoded blob | 
| Text data | A binary type | Set with matching media types | CONVERT\$1TO\$1TEXT | UTF8-encoded string | 
| Binary data | A text type | Set with matching media types | Undefined | Base64-encoded string | 
| Binary data | A text type | Set with matching media types | CONVERT\$1TO\$1BINARY | Binary data | 
| Binary data | A text type | Set with matching media types | CONVERT\$1TO\$1TEXT | Base64-encoded string | 
| Binary data | A binary type | Set with matching media types | Undefined | Binary data | 
| Binary data | A binary type | Set with matching media types | CONVERT\$1TO\$1BINARY | Binary data | 
| Binary data | A binary type | Set with matching media types | CONVERT\$1TO\$1TEXT | Base64-encoded string | 

When converting a text payload to a binary blob, API Gateway assumes that the text data is a base64-encoded string and outputs the binary data as a base64-decoded blob. If the conversion fails, it returns a `500` response, which indicates an API configuration error. You don't provide a mapping template for such a conversion, although you must enable the [passthrough behaviors](integration-passthrough-behaviors.md) on the API.

When converting a binary payload to a text string, API Gateway always applies a base64 encoding on the binary data. You can define a mapping template for such a payload, but can only access the base64-encoded string in the mapping template through `$input.body`, as shown in the following excerpt of an example mapping template. 

```
{   
    "data": "$input.body"
}
```

To have the binary payload passed through without modification, you must enable the [passthrough behaviors](integration-passthrough-behaviors.md) on the API. 

# Enabling binary support using the API Gateway console


The section explains how to enable binary support using the API Gateway console. As an example, we use an API that is integrated with Amazon S3. We focus on the tasks to set the supported media types and to specify how the payload should be handled. For detailed information on how to create an API integrated with Amazon S3, see [Tutorial: Create a REST API as an Amazon S3 proxy](integrating-api-with-aws-services-s3.md).

**To enable binary support by using the API Gateway console**

1. Set binary media types for the API:

   1. Create a new API or choose an existing API. For this example, we name the API `FileMan`.

   1. Under the selected API in the primary navigation panel, choose **API settings**.

   1. In the **API settings** pane, choose **Manage media types** in the **Binary Media Types** section.

   1. Choose **Add binary media type**.

   1. Enter a required media type, for example, **image/png**, in the input text field. If needed, repeat this step to add more media types. To support all binary media types, specify `*/*`.

   1. Choose **Save changes**.

1. Set how message payloads are handled for the API method:

   1. Create a new or choose an existing resource in the API. For this example, we use the `/{folder}/{item}` resource.

   1. Create a new or choose an existing method on the resource. As an example, we use the `GET /{folder}/{item}` method integrated with the `Object GET` action in Amazon S3. 

   1. For **Content handling**, choose an option. 

       

      Choose **Passthrough** if you don't want to convert the body when the client and backend accepts the same binary format. Choose **Convert to text** to convert the binary body to a base64-encoded string when, for example, the backend requires that a binary request payload is passed in as a JSON property. And choose **Convert to binary** when the client submits a base64-encoded string and the backend requires the original binary format, or when the endpoint returns a base64-encoded string and the client accepts only the binary output.

   1. For **Request body passthrough**, choose **When there are no templates defined (recommended)** to enable the passthrough behavior on the request body.

      You could also choose **Never**. This means that the API will reject data with content-types that do not have a mapping template.

   1. Preserve the incoming request's `Accept` header in the integration request. You should do this if you've set `contentHandling` to `passthrough` and want to override that setting at runtime.

       

   1. For conversion to text, define a mapping template to put the base64-encoded binary data into the required format.

      An example of a mapping template to convert to text is the following:

      ```
      {
        "operation": "thumbnail",
        "base64Image": "$input.body"
      }
      ```

      The format of this mapping template depends on the endpoint requirements of the input.

   1. Choose **Save**.

# Enabling binary support using the API Gateway REST API


The following tasks show how to enable binary support using the API Gateway REST API calls.

**Topics**
+ [

## Add and update supported binary media types to an API
](#api-gateway-payload-encodings-setup-with-api-set-encodings-map)
+ [

## Configure request payload conversions
](#api-gateway-payload-encodings-setup-with-api-set-integration-request-encoding)
+ [

## Configure response payload conversions
](#api-gateway-payload-encodings-setup-with-api-set-integration-response-encoding)
+ [

## Convert binary data to text data
](#api-gateway-payload-encodings-convert-binary-to-string)
+ [

## Convert text data to a binary payload
](#api-gateway-payload-encodings-convert-string-to-binary)
+ [

## Pass through a binary payload
](#api-gateway-payload-encodings-pass-binary-as-is)

## Add and update supported binary media types to an API


To enable API Gateway to support a new binary media type, you must add the binary media type to the `binaryMediaTypes` list of the `RestApi` resource. For example, to have API Gateway handle JPEG images, submit a `PATCH` request to the `RestApi` resource: 

```
PATCH /restapis/<restapi_id>

{
  "patchOperations" : [ {
    "op" : "add",
    "path" : "/binaryMediaTypes/image~1jpeg"
  } 
 ]
}
```

The MIME type specification of `image/jpeg` that is part of the `path` property value is escaped as `image~1jpeg`.

To update the supported binary media types, replace or remove the media type from the `binaryMediaTypes` list of the `RestApi` resource. For example, to change binary support from JPEG files to raw bytes, submit a `PATCH` request to the `RestApi` resource, as follows: 

```
PATCH /restapis/<restapi_id>

{
  "patchOperations" : [{
    "op" : "replace",
    "path" : "/binaryMediaTypes/image~1jpeg",
    "value" : "application/octet-stream"
  },
  {
    "op" : "remove",
    "path" : "/binaryMediaTypes/image~1jpeg"
  }]
}
```

## Configure request payload conversions


If the endpoint requires a binary input, set the `contentHandling` property of the `Integration` resource to `CONVERT_TO_BINARY`. To do so, submit a `PATCH` request, as follows: 

```
PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration

{
  "patchOperations" : [ {
    "op" : "replace",
    "path" : "/contentHandling",
    "value" : "CONVERT_TO_BINARY"
  }]
}
```

## Configure response payload conversions


If the client accepts the result as a binary blob instead of a base64-encoded payload returned from the endpoint, set the `contentHandling` property of the `IntegrationResponse` resource to `CONVERT_TO_BINARY`. To do this, submit a `PATCH` request, as follows:

```
PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration/responses/<status_code>

{
  "patchOperations" : [ {
    "op" : "replace",
    "path" : "/contentHandling",
    "value" : "CONVERT_TO_BINARY"
  }]
}
```

## Convert binary data to text data


To send binary data as a JSON property of the input to Amazon Lambda or Kinesis through API Gateway, do the following: 

1. Enable the binary payload support of the API by adding the new binary media type of `application/octet-stream` to the API's `binaryMediaTypes` list. 

   ```
   PATCH /restapis/<restapi_id>
   
   {
     "patchOperations" : [ {
       "op" : "add",
       "path" : "/binaryMediaTypes/application~1octet-stream"
     } 
    ]
   }
   ```

1. Set `CONVERT_TO_TEXT` on the `contentHandling` property of the `Integration` resource and provide a mapping template to assign the base64-encoded string of the binary data to a JSON property. In the following example, the JSON property is `body` and `$input.body` holds the base64-encoded string.

   ```
   PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration
   
   {
     "patchOperations" : [
       {
         "op" : "replace",
         "path" : "/contentHandling",
         "value" : "CONVERT_TO_TEXT"
       },
       {
         "op" : "add",
         "path" : "/requestTemplates/application~1octet-stream",
         "value" : "{\"body\": \"$input.body\"}"
       }
     ]
   }
   ```

## Convert text data to a binary payload


Suppose a Lambda function returns an image file as a base64-encoded string. To pass this binary output to the client through API Gateway, do the following: 

1. Update the API's `binaryMediaTypes` list by adding the binary media type of `application/octet-stream`, if it is not already in the list. 

   ```
   PATCH /restapis/<restapi_id>
   
   {
     "patchOperations" : [ {
       "op" : "add",
       "path" : "/binaryMediaTypes/application~1octet-stream",
     }]
   }
   ```

1.  Set the `contentHandling` property on the `Integration` resource to `CONVERT_TO_BINARY`. Do not define a mapping template. If you don't define a mapping template, API Gateway invokes the passthrough template to return the base64-decoded binary blob as the image file to the client. 

   ```
   PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration/responses/<status_code>
   
   {
     "patchOperations" : [
       {
         "op" : "replace",
         "path" : "/contentHandling",
         "value" : "CONVERT_TO_BINARY"
       }
     ]
   }
   ```

## Pass through a binary payload


 To store an image in an Amazon S3 bucket using API Gateway, do the following: 

1. Update the API's `binaryMediaTypes` list by adding the binary media type of `application/octet-stream`, if it isn't already in the list. 

   ```
   PATCH /restapis/<restapi_id>
   
   {
     "patchOperations" : [ {
       "op" : "add",
       "path" : "/binaryMediaTypes/application~1octet-stream"
     }
    ]
   }
   ```

1. On the `contentHandling` property of the `Integration` resource, set `CONVERT_TO_BINARY`. Set `WHEN_NO_MATCH` as the `passthroughBehavior` property value without defining a mapping template. This enables API Gateway to invoke the passthrough template. 

   ```
   PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration
   
   {
     "patchOperations" : [
       {
         "op" : "replace",
         "path" : "/contentHandling",
         "value" : "CONVERT_TO_BINARY"
       },
       {
         "op" : "replace",
         "path" : "/passthroughBehaviors",
         "value" : "WHEN_NO_MATCH"
       }
     ]
   }
   ```

# Import and export content encodings for API Gateway


 To import the `binaryMediaTypes` list on a [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html), use the following API Gateway extension to the API's OpenAPI definition file. The extension is also used to export the API settings.
+ [x-amazon-apigateway-binary-media-types property](api-gateway-swagger-extensions-binary-media-types.md)

To import and export the `contentHandling` property value on an `Integration` or `IntegrationResponse` resource, use the following API Gateway extensions to the OpenAPI definitions:
+ [x-amazon-apigateway-integration object](api-gateway-swagger-extensions-integration.md)
+ [x-amazon-apigateway-integration.response object](api-gateway-swagger-extensions-integration-response.md)

# Return binary media from a Lambda proxy integration in API Gateway


To return binary media from an [Amazon Lambda proxy integration](set-up-lambda-proxy-integrations.md), base64 encode the response from your Lambda function. You must also [configure your API's binary media types](api-gateway-payload-encodings-configure-with-console.md). When you configure your API's binary media types, your API treats that content type as binary data. The payload size limit is 10 MB.

**Note**  
To use a web browser to invoke an API with this example integration, set your API's binary media types to `*/*`. API Gateway uses the first `Accept` header from clients to determine if a response should return binary media. To return binary media when you can't control the order of `Accept` header values, such as requests from a browser, set your API's binary media types to `*/*` (for all content types).

The following example Lambda function can return a binary image from Amazon S3 or text to clients. The function's response includes a `Content-Type` header to indicate to the client the type of data that it returns. The function conditionally sets the `isBase64Encoded` property in its response, depending on the type of data that it returns.

------
#### [ Node.js ]

```
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"

const client = new S3Client({region: 'us-west-2'});

export const handler = async (event) => {

  var randomint = function(max) {
    return Math.floor(Math.random() * max);
  }
  var number = randomint(2);
  if (number == 1){ 
    const input = {
      "Bucket" : "bucket-name",
      "Key" : "image.png"
      }
    try {
      const command = new GetObjectCommand(input)
      const response = await client.send(command);
      var str = await response.Body.transformToByteArray();
    } catch (err) {
      console.error(err);
    }
    const base64body = Buffer.from(str).toString('base64');
    return {
      'headers': { "Content-Type": "image/png" },
      'statusCode': 200,
      'body': base64body,
      'isBase64Encoded': true
      }
    } else {
        return {
        'headers': { "Content-Type": "text/html" },
        'statusCode': 200,
        'body': "<h1>This is text</h1>",
        }
    }
}
```

------
#### [ Python ]

```
import base64
import boto3
import json
import random

s3 = boto3.client('s3')

def lambda_handler(event, context):
    number = random.randint(0,1)
    if number == 1:
        response = s3.get_object(
            Bucket='bucket-name',
            Key='image.png',
        )
        image = response['Body'].read()
        return {
            'headers': { "Content-Type": "image/png" },
            'statusCode': 200,
            'body': base64.b64encode(image).decode('utf-8'),
            'isBase64Encoded': True
        }
    else:
        return {
            'headers': { "Content-type": "text/html" },
            'statusCode': 200,
            'body': "<h1>This is text</h1>",
        }
```

------

To learn more about binary media types, see [Binary media types for REST APIs in API Gateway](api-gateway-payload-encodings.md).

# Access binary files in Amazon S3 through an API Gateway API


The following examples show the OpenAPI file used to access images in Amazon S3, how to download an image from Amazon S3, and how to upload an image to Amazon S3. 

**Topics**
+ [

## OpenAPI file of a sample API to access images in Amazon S3
](#api-gateway-content-encodings-example-image-s3-swagger-file)
+ [

## Download an image from Amazon S3
](#api-gateway-content-encodings-example-download-image-from-s3)
+ [

## Upload an image to Amazon S3
](#api-gateway-content-encodings-example-upload-image-to-s3)

## OpenAPI file of a sample API to access images in Amazon S3


The following OpenAPI file shows a sample API that illustrates downloading an image file from Amazon S3 and uploading an image file to Amazon S3. This API exposes the `GET /s3?key={file-name}` and `PUT /s3?key={file-name}` methods for downloading and uploading a specified image file. The `GET` method returns the image file as a base64-encoded string as part of a JSON output, following the supplied mapping template, in a 200 OK response. The `PUT` method takes a raw binary blob as input and returns a 200 OK response with an empty payload.

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

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-10-21T17:26:28Z",
      "title": "ApiName"
   },
   "paths": {
      "/s3": {
         "get": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200"
                  }
               },
               "requestParameters": {
                  "integration.request.path.key": "method.request.querystring.key"
               },
               "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "GET",
               "type": "aws"
            }
         },
         "put": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     },
                     "application/octet-stream": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200"
                  }
               },
               "requestParameters": {
                  "integration.request.path.key": "method.request.querystring.key"
               },
               "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "PUT",
               "type": "aws",
               "contentHandling": "CONVERT_TO_BINARY"
            }
         }
      }
   },
   "x-amazon-apigateway-binary-media-types": [
      "application/octet-stream",
      "image/jpeg"
   ],
   "servers": [
      {
         "url": "https://abcdefghi.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/v1"
            }
         }
      }
   ],
   "components": {
      "schemas": {
         "Empty": {
            "type": "object",
            "title": "Empty Schema"
         }
      }
   }
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-10-21T17:26:28Z",
    "title": "ApiName"
  },
  "host": "abcdefghi.execute-api.us-east-1.amazonaws.com",
  "basePath": "/v1",
  "schemes": [
    "https"
  ],
  "paths": {
    "/s3": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200"            }
          },
          "requestParameters": {
            "integration.request.path.key": "method.request.querystring.key"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      },
      "put": {
        "produces": [
          "application/json", "application/octet-stream"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.path.key": "method.request.querystring.key"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "PUT",
          "type": "aws",
          "contentHandling" : "CONVERT_TO_BINARY"
        }
      }
    }
  },
  "x-amazon-apigateway-binary-media-types" : ["application/octet-stream", "image/jpeg"],
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------

## Download an image from Amazon S3


To download an image file (`image.jpg`) as a binary blob from Amazon S3:

```
GET /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/octet-stream
```

The successful response looks like this:

```
200 OK HTTP/1.1

[raw bytes]
```

The raw bytes are returned because the `Accept` header is set to a binary media type of `application/octet-stream` and binary support is enabled for the API. 

Alternatively, to download an image file (`image.jpg`) as a base64-encoded string (formatted as a JSON property) from Amazon S3, add a response template to the 200 integration response, as shown in the following bold-faced OpenAPI definition block:

```
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "{\n   \"image\": \"$input.body\"\n}"
              }
            }
          },
```

The request to download the image file looks like the following:

```
GET /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json
```

The successful response looks like the following:

```
200 OK HTTP/1.1

{
  "image": "W3JhdyBieXRlc10="
}
```

## Upload an image to Amazon S3


To upload an image file (`image.jpg`) as a binary blob to Amazon S3:

```
PUT /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/octet-stream
Accept: application/json

[raw bytes]
```

The successful response looks like the following:

```
200 OK HTTP/1.1        
```

To upload an image file (`image.jpg`) as a base64-encoded string to Amazon S3:

```
PUT /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json

W3JhdyBieXRlc10=
```

The input payload must be a base64-encoded string because the `Content-Type` header value is set to `application/json`. The successful response looks like the following:

```
200 OK HTTP/1.1
```

# Access binary files in Lambda using an API Gateway API


The following OpenAPI example demonstrates how to access a binary file in Amazon Lambda through an API Gateway API. This API exposes the `GET /lambda?key={file-name}` and the `PUT /lambda?key={file-name}` methods for downloading and uploading a specified image file. The `GET` method returns the image file as a base64-encoded string as part of a JSON output, following the supplied mapping template, in a 200 OK response. The `PUT` method takes a raw binary blob as input and returns a 200 OK response with an empty payload.

You create the Lambda function that your API calls, and it must return a base64-encoded string with the `Content-Type` header of `application/json`. 

**Topics**
+ [

## OpenAPI file of a sample API to access images in Lambda
](#api-gateway-content-encodings-example-image-lambda-swagger-file)
+ [

## Download an image from Lambda
](#api-gateway-content-encodings-example-download-image-from-lambda)
+ [

## Upload an image to Lambda
](#api-gateway-content-encodings-example-upload-image-to-lambda)

## OpenAPI file of a sample API to access images in Lambda


The following OpenAPI file shows an example API that illustrates downloading an image file from Lambda and uploading an image file to Lambda.

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

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-10-21T17:26:28Z",
      "title": "ApiName"
   },
   "paths": {
      "/lambda": {
         "get": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
               "type": "AWS",
               "credentials": "arn:aws:iam::123456789012:role/Lambda",
               "httpMethod": "POST",
               "requestTemplates": {
                  "application/json": "{\n   \"imageKey\": \"$input.params('key')\"\n}"
               },
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200",
                     "responseTemplates": {
                        "application/json": "{\n   \"image\": \"$input.body\"\n}"
                     }
                  }
               }
            }
         },
         "put": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     },
                     "application/octet-stream": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
               "type": "AWS",
               "credentials": "arn:aws:iam::123456789012:role/Lambda",
               "httpMethod": "POST",
               "contentHandling": "CONVERT_TO_TEXT",
               "requestTemplates": {
                  "application/json": "{\n   \"imageKey\": \"$input.params('key')\", \"image\": \"$input.body\"\n}"
               },
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200"
                  }
               }
            }
         }
      }
   },
   "x-amazon-apigateway-binary-media-types": [
      "application/octet-stream",
      "image/jpeg"
   ],
   "servers": [
      {
         "url": "https://abcdefghi.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/v1"
            }
         }
      }
   ],
   "components": {
      "schemas": {
         "Empty": {
            "type": "object",
            "title": "Empty Schema"
         }
      }
   }
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-10-21T17:26:28Z",
    "title": "ApiName"
  },
  "host": "abcdefghi.execute-api.us-east-1.amazonaws.com",
  "basePath": "/v1",
  "schemes": [
    "https"
  ],
  "paths": {
    "/lambda": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
          "type": "AWS",
          "credentials": "arn:aws:iam::123456789012:role/Lambda",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n   \"imageKey\": \"$input.params('key')\"\n}"
          },
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "{\n   \"image\": \"$input.body\"\n}"
              }
            }
          }
        }
      },
      "put": {
        "produces": [
          "application/json", "application/octet-stream"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
          "type": "AWS",
          "credentials": "arn:aws:iam::123456789012:role/Lambda",
          "httpMethod": "POST",
          "contentHandling" : "CONVERT_TO_TEXT",
          "requestTemplates": {
            "application/json": "{\n   \"imageKey\": \"$input.params('key')\", \"image\": \"$input.body\"\n}"
          },
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200"
            }
          }
        }
      }
    }
  },
  "x-amazon-apigateway-binary-media-types" : ["application/octet-stream", "image/jpeg"],
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------

## Download an image from Lambda


To download an image file (`image.jpg`) as a binary blob from Lambda:

```
GET /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/octet-stream
```

The successful response looks like the following:

```
200 OK HTTP/1.1

[raw bytes]
```

To download an image file (`image.jpg`) as a base64-encoded string (formatted as a JSON property) from Lambda:

```
GET /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json
```

The successful response looks like the following:

```
200 OK HTTP/1.1

{
  "image": "W3JhdyBieXRlc10="
}
```

## Upload an image to Lambda


To upload an image file (`image.jpg`) as a binary blob to Lambda:

```
PUT /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/octet-stream
Accept: application/json

[raw bytes]
```

The successful response looks like the following:

```
200 OK            
```

To upload an image file (`image.jpg`) as a base64-encoded string to Lambda:

```
PUT /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json

W3JhdyBieXRlc10=
```

The successful response looks like the following:

```
200 OK           
```

# Invoke REST APIs in API Gateway
Invoke

To call a deployed API, clients submit requests to the URL for the API Gateway component service for API execution, known as `execute-api`.

The base URL for REST APIs is in the following format: 

```
https://api-id.execute-api.region.amazonaws.com/stage/
```

where *api-id* is the API identifier, *region* is the Amazon Region, and *stage* is the stage name of the API deployment. 

**Important**  
Before you can invoke an API, you must deploy it in API Gateway. For instructions on deploying an API, see [Deploy REST APIs in API Gateway](how-to-deploy-api.md). 

**Topics**
+ [

## Obtaining an API's invoke URL
](#apigateway-how-to-call-rest-api)
+ [

## Invoking an API
](#apigateway-call-api)
+ [

# Use the API Gateway console to test a REST API method
](how-to-test-method.md)
+ [

# Use a Java SDK generated by API Gateway for a REST API
](how-to-call-apigateway-generated-java-sdk.md)
+ [

# Use an Android SDK generated by API Gateway for a REST API
](how-to-generate-sdk-android.md)
+ [

# Use a JavaScript SDK generated by API Gateway for a REST API
](how-to-generate-sdk-javascript.md)
+ [

# Use a Ruby SDK generated by API Gateway for a REST API
](how-to-call-sdk-ruby.md)
+ [

# Use iOS SDK generated by API Gateway for a REST API in Objective-C or Swift
](how-to-generate-sdk-ios.md)

## Obtaining an API's invoke URL


You can use the console, the Amazon CLI, or an exported OpenAPI definition to obtain an API's invoke URL.

### Obtaining an API's invoke URL using the console


The following procedure shows how to obtain an API's invoke URL in the REST API console.

**To obtain an API's invoke URL using the REST API console**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a deployed API.

1. From the main navigation pane, choose **Stage**.

1. Under **Stage details**, choose the copy icon to copy your API's invoke URL.

   This URL is for the root resource of your API.

1. To obtain an API's invoke URL for another resource in your API, expand the stage under the secondary navigation pane, and then choose a method.

1. Choose the copy icon to copy your API's resource-level invoke URL.

#### Obtaining an API's invoke URL using the Amazon CLI


The following procedure shows how to obtain an API's invoke URL using the Amazon CLI.

**To obtain an API's invoke URL using the Amazon CLI**

1. Use the following command to obtain the `rest-api-id`. This command returns all `rest-api-id` values in your Region. For more information, see [get-rest-apis](https://docs.amazonaws.cn/cli/latest/reference/apigateway/get-rest-apis.html).

   ```
   aws apigateway get-rest-apis
   ```

1. Replace the example `rest-api-id` with your `rest-api-id`, replace the example *\$1stage-name\$1* with your *\$1stage-name\$1*, and replace the *\$1region\$1*, with your Region.

   ```
   https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}/
   ```

##### Obtaining an API's invoke URL using the exported OpenAPI definition file of the API


You can also construct the root URL by combining the `host` and `basePath` fields of an exported OpenAPI definition file of the API. For instructions on how to export your API, see [Export a REST API from API Gateway](api-gateway-export-api.md).

## Invoking an API


You can call your deployed API using the browser, curl, or other applications, like [Postman](https://www.postman.com/).

Additionally, you can use the API Gateway console to test an API call. Test uses the API Gateway's `TestInvoke` feature, which allows API testing before the API is deployed. For more information, see [Use the API Gateway console to test a REST API method](how-to-test-method.md).

**Note**  
Query string parameter values in an invocation URL cannot contain `%%`.

### Invoking an API using a web browser


If your API permits anonymous access, you can use any web browser to invoke any `GET` method. Enter the complete invocation URL in the browser's address bar.

For other methods or any authentication-required calls, you must specify a payload or sign the requests. You can handle these in a script behind an HTML page or in a client application using one of the Amazon SDKs.

#### Invoking an API using curl


You can use a tool like [curl](https://curl.se/) in your terminal to call your API. The following example curl command invokes the GET method on the `getUsers` resource of the `prod` stage of an API.

------
#### [ Linux or Macintosh ]

```
curl -X GET 'https://b123abcde4.execute-api.us-west-2.amazonaws.com/prod/getUsers'
```

------
#### [ Windows ]

```
curl -X GET "https://b123abcde4.execute-api.us-west-2.amazonaws.com/prod/getUsers"
```

------

# Use the API Gateway console to test a REST API method
Use the console to test a REST API method

Use the API Gateway console to test a REST API method.

**Topics**
+ [

## Prerequisites
](#how-to-test-method-prerequisites)
+ [

## Test a method with the API Gateway console
](#how-to-test-method-console)

## Prerequisites

+ You must specify the settings for the methods you want to test. Follow the instructions in [Methods for REST APIs in API Gateway](how-to-method-settings.md).

## Test a method with the API Gateway console


**Important**  
Testing methods with the API Gateway console might result in changes to resources that cannot be undone. Testing a method with the API Gateway console is the same as calling the method outside of the API Gateway console. For example, if you use the API Gateway console to call a method that deletes an API's resources, if the method call is successful, the API's resources will be deleted.

**To test a method**

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose a REST API.

1. In the **Resources** pane, choose the method you want to test.

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

    Enter values in any of the displayed boxes (such as **Query strings**, **Headers**, and **Request body**). The console includes these values in the method request in default application/json form.

   For additional options you might need to specify, contact the API owner.

1. Choose **Test**. The following information will be displayed:
   + **Request** is the resource's path that was called for the method.
   + **Status** is the response's HTTP status code.
   + **Latency (ms)** is the time between the receipt of the request from the caller and the returned response.
   + **Response body** is the HTTP response body.
   + **Response headers** are the HTTP response headers.
**Tip**  
Depending on the mapping, the HTTP status code, response body, and response headers might be different from those sent from the Lambda function, HTTP proxy, or Amazon service proxy.
   + **Logs** are the simulated Amazon CloudWatch Logs entries that would have been written if this method were called outside of the API Gateway console.
**Note**  
Although the CloudWatch Logs entries are simulated, the results of the method call are real.

 In addition to using the API Gateway console, you can use Amazon CLI or an Amazon SDK for API Gateway to test invoking a method. To do so using Amazon CLI, see [test-invoke-method](https://docs.amazonaws.cn/cli/latest/reference/apigateway/test-invoke-method.html). 

# Use a Java SDK generated by API Gateway for a REST API


In this section, we outline the steps to use a Java SDK generated by API Gateway for a REST API, by using the [Simple Calculator](simple-calc-lambda-api-swagger-definition.md) API as an example. Before proceeding, you must complete the steps in [Generate SDKs for REST APIs in API Gateway](how-to-generate-sdk.md). 

**To install and use a Java SDK generated by API Gateway**

1. Extract the contents of the API Gateway-generated .zip file that you downloaded earlier.

1. Download and install [Apache Maven](https://maven.apache.org/) (must be version 3.5 or later).

1. Download and install [JDK 8](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html).

1. Set the `JAVA_HOME` environment variable.

1.  Go to the unzipped SDK folder where the pom.xml file is located. This folder is `generated-code` by default. Run the **mvn install** command to install the compiled artifact files to your local Maven repository. This creates a `target` folder containing the compiled SDK library. 

1.  Type the following command in an empty directory to create a client project stub to call the API using the installed SDK library. 

   ```
   mvn -B archetype:generate \
       -DarchetypeGroupdId=org.apache.maven.archetypes \
       -DgroupId=examples.aws.apig.simpleCalc.sdk.app \
       -DartifactId=SimpleCalc-sdkClient
   ```
**Note**  
 The separator `\` in the preceding command is included for readability. The whole command should be on a single line without the separator. 

    This command creates an application stub. The application stub contains a `pom.xml` file and an `src` folder under the project's root directory (*SimpleCalc-sdkClient* in the preceding command). Initially, there are two source files: `src/main/java/{package-path}/App.java` and `src/test/java/{package-path}/AppTest.java`. In this example, *\$1package-path\$1* is `examples/aws/apig/simpleCalc/sdk/app`. This package path is derived from the `DarchetypeGroupdId` value. You can use the `App.java` file as a template for your client application, and you can add others in the same folder if needed. You can use the `AppTest.java` file as a unit test template for your application, and you can add other test code files to the same test folder as needed. 

1. Update the package dependencies in the generated `pom.xml` file to the following, substituting your project's `groupId`, `artifactId`, `version`, and `name` properties, if necessary:

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>examples.aws.apig.simpleCalc.sdk.app</groupId>
     <artifactId>SimpleCalc-sdkClient</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>SimpleCalc-sdkClient</name>
     <url>http://maven.apache.org</url>
   
      <dependencies>
         <dependency>
             <groupId>com.amazonaws</groupId>
             <artifactId>aws-java-sdk-core</artifactId>
             <version>1.11.94</version>
         </dependency>
         <dependency>
             <groupId>my-apig-api-examples</groupId>
             <artifactId>simple-calc-sdk</artifactId>
             <version>1.0.0</version>
         </dependency>
         
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.12</version>
         <scope>test</scope>
       </dependency>
   
       <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.5</version>
       </dependency>    
     </dependencies>
   
     <build>
       <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.5.1</version>
           <configuration>
             <source>1.8</source>
             <target>1.8</target>
           </configuration>
         </plugin>
       </plugins>
     </build>
   </project>
   ```
**Note**  
 When a newer version of dependent artifact of `aws-java-sdk-core` is incompatible with the version specified above (`1.11.94`), you must update the `<version>` tag to the new version.

1.  Next, we show how to call the API using the SDK by calling the `getABOp(GetABOpRequest req)`, `getApiRoot(GetApiRootRequest req)`, and `postApiRoot(PostApiRootRequest req)` methods of the SDK. These methods correspond to the `GET /{a}/{b}/{op}`, `GET /?a={x}&b={y}&op={operator}`, and `POST /` methods, with a payload of `{"a": x, "b": y, "op": "operator"}` API requests, respectively. 

    Update the `App.java` file as follows: 

   ```
   package examples.aws.apig.simpleCalc.sdk.app;
   
   import java.io.IOException;
   
   import com.amazonaws.opensdk.config.ConnectionConfiguration;
   import com.amazonaws.opensdk.config.TimeoutConfiguration;
   
   import examples.aws.apig.simpleCalc.sdk.*;
   import examples.aws.apig.simpleCalc.sdk.model.*;
   import examples.aws.apig.simpleCalc.sdk.SimpleCalcSdk.*;
   
   public class App 
   {
       SimpleCalcSdk sdkClient;
   
       public App() {
           initSdk();
       }
   
       // The configuration settings are for illustration purposes and may not be a recommended best practice.
       private void initSdk() {
           sdkClient = SimpleCalcSdk.builder()
                 .connectionConfiguration(
                     new ConnectionConfiguration()
                           .maxConnections(100)
                           .connectionMaxIdleMillis(1000))
                 .timeoutConfiguration(
                     new TimeoutConfiguration()
                           .httpRequestTimeout(3000)
                           .totalExecutionTimeout(10000)
                           .socketTimeout(2000))
           .build();
   
       }
       // Calling shutdown is not necessary unless you want to exert explicit control of this resource.
       public void shutdown() {
           sdkClient.shutdown();
       }
        
       // GetABOpResult getABOp(GetABOpRequest getABOpRequest)
       public Output getResultWithPathParameters(String x, String y, String operator) {
       	operator = operator.equals("+") ? "add" : operator;
       	operator = operator.equals("/") ? "div" : operator; 
   
           GetABOpResult abopResult = sdkClient.getABOp(new GetABOpRequest().a(x).b(y).op(operator));
           return abopResult.getResult().getOutput();
       }
   
       public Output getResultWithQueryParameters(String a, String b, String op) {
           GetApiRootResult rootResult = sdkClient.getApiRoot(new GetApiRootRequest().a(a).b(b).op(op));
           return rootResult.getResult().getOutput();
       }
   
       public Output getResultByPostInputBody(Double x, Double y, String o) {
       	PostApiRootResult postResult = sdkClient.postApiRoot(
       		new PostApiRootRequest().input(new Input().a(x).b(y).op(o)));
       	return postResult.getResult().getOutput();
       }
   
       public static void main( String[] args )
       {
           System.out.println( "Simple calc" );
           // to begin
           App calc = new App();
           
           // call the SimpleCalc API
           Output res = calc.getResultWithPathParameters("1", "2", "-");
           System.out.printf("GET /1/2/-: %s\n", res.getC());
   
           // Use the type query parameter
           res = calc.getResultWithQueryParameters("1", "2", "+");
           System.out.printf("GET /?a=1&b=2&op=+: %s\n", res.getC());
   
           // Call POST with an Input body.
           res = calc.getResultByPostInputBody(1.0, 2.0, "*");
           System.out.printf("PUT /\n\n{\"a\":1, \"b\":2,\"op\":\"*\"}\n %s\n", res.getC());
   
           
       }
   }
   ```

    In the preceding example, the configuration settings used to instantiate the SDK client are for illustration purposes and are not necessarily recommended best practice. Also, calling `sdkClient.shutdown()` is optional, especially if you need precise control on when to free up resources. 

 We have shown the essential patterns to call an API using a Java SDK. You can extend the instructions to calling other API methods. 

# Use an Android SDK generated by API Gateway for a REST API


In this section, we will outline the steps to use an Android SDK generated by API Gateway for a REST API. Before proceeding further, you must have already completed the steps in [Generate SDKs for REST APIs in API Gateway](how-to-generate-sdk.md).

**Note**  
 The generated SDK is not compatible with Android 4.4 and earlier. For more information, see [Amazon API Gateway important notes](api-gateway-known-issues.md). 

**To install and use an Android SDK generated by API Gateway**

1. Extract the contents of the API Gateway-generated .zip file that you downloaded earlier.

1. Download and install [Apache Maven](https://maven.apache.org/) (preferably version 3.x).

1. Download and install [JDK 8](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html).

1. Set the `JAVA_HOME` environment variable.

1. Run the **mvn install** command to install the compiled artifact files to your local Maven repository. This creates a `target` folder containing the compiled SDK library.

1. Copy the SDK file (the name of which is derived from the **Artifact Id** and **Artifact Version** you specified when generating the SDK, e.g., `simple-calcsdk-1.0.0.jar`) from the `target` folder, along with all of the other libraries from the `target/lib` folder, into your project's `lib` folder.

   If you use Android Studio, create a `libs` folder under your client app module and copy the required .jar file into this folder. Verify that the dependencies section in the module's gradle file contains the following.

   ```
       compile fileTree(include: ['*.jar'], dir: 'libs')
       compile fileTree(include: ['*.jar'], dir: 'app/libs')
   ```

   Make sure no duplicated .jar files are declared.

1. Use the `ApiClientFactory` class to initialize the API Gateway-generated SDK. For example:

   ```
   ApiClientFactory factory = new ApiClientFactory();
   
   // Create an instance of your SDK. Here, 'SimpleCalcClient.java' is the compiled java class for the SDK generated by API Gateway. 
   final SimpleCalcClient client = factory.build(SimpleCalcClient.class);
   
   // Invoke a method: 
   //   For the 'GET /?a=1&b=2&op=+' method exposed by the API, you can invoke it by calling the following SDK method:
   
   Result output = client.rootGet("1", "2", "+");
   
   //     where the Result class of the SDK corresponds to the Result model of the API.
   //
   
   //   For the 'GET /{a}/{b}/{op}'  method exposed by the API, you can call the following SDK method to invoke the request,
   
   Result output = client.aBOpGet(a, b, c);
   
   //     where a, b, c can be "1", "2", "add", respectively.
   
   //   For the following API method:
   //        POST /
   //        host: ...
   //        Content-Type: application/json
   //    
   //        { "a": 1, "b": 2, "op": "+" }
   // you can call invoke it by calling the rootPost method of the SDK as follows:
   Input body = new Input();
   input.a=1;
   input.b=2;
   input.op="+";
   Result output = client.rootPost(body);
   
   //      where the Input class of the SDK corresponds to the Input model of the API.
   
   // Parse the result:
   //     If the 'Result' object is { "a": 1, "b": 2, "op": "add", "c":3"}, you retrieve the result 'c') as 
   
   String result=output.c;
   ```

1. To use an Amazon Cognito credentials provider to authorize calls to your API, use the `ApiClientFactory` class to pass a set of Amazon credentials by using the SDK generated by API Gateway, as shown in the following example.

   ```
   // Use CognitoCachingCredentialsProvider to provide Amazon credentials
   // for the ApiClientFactory
   AWSCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
           context,          // activity context
           "identityPoolId", // Cognito identity pool id
           Regions.US_EAST_1 // region of Cognito identity pool
   );
   
   ApiClientFactory factory = new ApiClientFactory()
     .credentialsProvider(credentialsProvider);
   ```

1. To set an API key by using the API Gateway- generated SDK, use code similar to the following.

   ```
   ApiClientFactory factory = new ApiClientFactory()
     .apiKey("YOUR_API_KEY");
   ```

# Use a JavaScript SDK generated by API Gateway for a REST API


The following procedure shows how to use a JavaScript SDK generated by API Gateway.

**Note**  
These instructions assume you have already completed the instructions in [Generate SDKs for REST APIs in API Gateway](how-to-generate-sdk.md).

**Important**  
If your API only has ANY methods defined, the generated SDK package will not contain an `apigClient.js` file, and you will need to define the ANY methods yourself.

**To install, initiate and call a JavaScript SDK generated by API Gateway for a REST API**

1. Extract the contents of the API Gateway-generated .zip file you downloaded earlier.

1. Enable cross-origin resource sharing (CORS) for all of the methods the SDK generated by API Gateway will call. For instructions, see [CORS for REST APIs in API Gateway](how-to-cors.md).

1. In your web page, include references to the following scripts.

   ```
   <script type="text/javascript" src="lib/axios/dist/axios.standalone.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/rollups/hmac-sha256.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/rollups/sha256.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/components/hmac.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/components/enc-base64.js"></script>
   <script type="text/javascript" src="lib/url-template/url-template.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/sigV4Client.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/apiGatewayClient.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/simpleHttpClient.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/utils.js"></script>
   <script type="text/javascript" src="apigClient.js"></script>
   ```

1. In your code, initialize the SDK generated by API Gateway by using code similar to the following.

   ```
   var apigClient = apigClientFactory.newClient();
   ```

   To initialize the SDK generated by API Gateway with Amazon credentials, use code similar to the following. If you use Amazon credentials, all requests to the API will be signed. 

   ```
   var apigClient = apigClientFactory.newClient({
     accessKey: 'ACCESS_KEY',
     secretKey: 'SECRET_KEY',
   });
   ```

   To use an API key with the SDK generated by API Gateway, pass the API key as a parameter to the `Factory` object by using code similar to the following. If you use an API key, it is specified as part of the `x-api-key` header and all requests to the API will be signed. This means you must set the appropriate CORS Accept headers for each request.

   ```
   var apigClient = apigClientFactory.newClient({
     apiKey: 'API_KEY'
   });
   ```

   

1. Call the API methods in API Gateway by using code similar to the following. Each call returns a promise with a success and failure callbacks.

   ```
   var params = {
     // This is where any modeled request parameters should be added.
     // The key is the parameter name, as it is defined in the API in API Gateway.
     param0: '',
     param1: ''
   };
   
   var body = {
     // This is where you define the body of the request,
   };
   
   var additionalParams = {
     // If there are any unmodeled query parameters or headers that must be
     //   sent with the request, add them here.
     headers: {
       param0: '',
       param1: ''
     },
     queryParams: {
       param0: '',
       param1: ''
     }
   };
   
   apigClient.methodName(params, body, additionalParams)
       .then(function(result){
         // Add success callback code here.
       }).catch( function(result){
         // Add error callback code here.
       });
   ```

   Here, the *methodName* is constructed from the method request's resource path and the HTTP verb. For the SimpleCalc API, the SDK methods for the API methods of 

   ```
   1. GET /?a=...&b=...&op=...
   2. POST /
   
      { "a": ..., "b": ..., "op": ...}
   3. GET /{a}/{b}/{op}
   ```

   the corresponding SDK methods are as follows:

   ```
   1. rootGet(params);      // where params={"a": ..., "b": ..., "op": ...} is resolved to the query parameters
   2. rootPost(null, body); // where body={"a": ..., "b": ..., "op": ...}
   3. aBOpGet(params);      // where params={"a": ..., "b": ..., "op": ...} is resolved to the path parameters
   ```

   

# Use a Ruby SDK generated by API Gateway for a REST API


The following procedure shows how to use a Ruby SDK generated by API Gateway.

**Note**  
These instructions assume you already completed the instructions in [Generate SDKs for REST APIs in API Gateway](how-to-generate-sdk.md).

**To install, instantiate, and call a Ruby SDK generated by API Gateway for a REST API**

1. Unzip the downloaded Ruby SDK file. The generated SDK source is shown as follows.

   

1.  Build a Ruby Gem from the generated SDK source, using the following shell commands in a terminal window:

   ```
   # change to /simplecalc-sdk directory
   cd simplecalc-sdk
   
   # build the generated gem
   gem build simplecalc-sdk.gemspec
   ```

   After this, **simplecalc-sdk-1.0.0.gem** becomes available.

1.  Install the gem:

   ```
   gem install simplecalc-sdk-1.0.0.gem
   ```

1.  Create a client application. Instantiate and initialize the Ruby SDK client in the app:

   ```
   require 'simplecalc-sdk'
   client = SimpleCalc::Client.new(
       http_wire_trace: true,
       retry_limit: 5,
       http_read_timeout: 50
   )
   ```

   If the API has authorization of the `AWS_IAM` type is configured, you can include the caller's Amazon credentials by supplying `accessKey` and `secretKey` during the initialization:

   ```
   require 'pet-sdk'
   client = Pet::Client.new(
       http_wire_trace: true,
       retry_limit: 5,
       http_read_timeout: 50,
       access_key_id: 'ACCESS_KEY',
       secret_access_key: 'SECRET_KEY'
   )
   ```

1.  Make API calls through the SDK in the app. 
**Tip**  
 If you are not familiar with the SDK method call conventions, you can review the `client.rb` file in the generated SDK `lib` folder. The folder contains documentation of each supported API method call.

   To discover supported operations:

   ```
   # to show supported operations:
   puts client.operation_names
   ```

   This results in the following display, corresponding to the API methods of `GET /?a={.}&b={.}&op={.}`, `GET /{a}/{b}/{op}`, and `POST /`, plus a payload of the `{a:"…", b:"…", op:"…"}` format, respectively:

   ```
   [:get_api_root, :get_ab_op, :post_api_root]
   ```

   To invoke the `GET /?a=1&b=2&op=+` API method, call the following the Ruby SDK method:

   ```
   resp = client.get_api_root({a:"1", b:"2", op:"+"})
   ```

   To invoke the `POST /` API method with a payload of `{a: "1", b: "2", "op": "+"}`, call the following Ruby SDK method:

   ```
   resp = client.post_api_root(input: {a:"1", b:"2", op:"+"})
   ```

   To invoke the `GET /1/2/+` API method, call the following Ruby SDK method:

   ```
   resp = client.get_ab_op({a:"1", b:"2", op:"+"})
   ```

   The successful SDK method calls return the following response:

   ```
   resp : {
       result: {
           input: {
               a: 1,
               b: 2,
               op: "+"
           },
           output: {
               c: 3
           }
       }
   }
   ```

# Use iOS SDK generated by API Gateway for a REST API in Objective-C or Swift


In this tutorial, we will show how to use an iOS SDK generated by API Gateway for a REST API in an Objective-C or Swift app to call the underlying API. We will use the [SimpleCalc API](simple-calc-lambda-api.md) as an example to illustrate the following topics:
+ How to install the required Amazon Mobile SDK components into your Xcode project
+ How to create the API client object before calling the API's methods
+ How to call the API methods through the corresponding SDK methods on the API client object
+ How to prepare a method input and parse its result using the corresponding model classes of the SDK

**Topics**
+ [

## Use generated iOS SDK (Objective-C) to call API
](#how-to-use-sdk-ios-objc)
+ [

## Use generated iOS SDK (Swift) to call API
](#how-to-generate-sdk-ios-swift)

## Use generated iOS SDK (Objective-C) to call API
Use generated iOS SDK (Objective-C) to call API

Before beginning the following procedure, you must complete the steps in [Generate SDKs for REST APIs in API Gateway](how-to-generate-sdk.md) for iOS in Objective-C and download the .zip file of the generated SDK.

### Install the Amazon mobile SDK and an iOS SDK generated by API Gateway in an Objective-C project


The following procedure describes how to install the SDK.

**To install and use an iOS SDK generated by API Gateway in Objective-C**

1. Extract the contents of the API Gateway-generated .zip file you downloaded earlier. Using the [SimpleCalc API](simple-calc-lambda-api.md), you may want to rename the unzipped SDK folder to something like **sdk\$1objc\$1simple\$1calc**. In this SDK folder there is a `README.md` file and a `Podfile` file. The `README.md` file contains the instructions to install and use the SDK. This tutorial provides details about these instructions. The installation leverages [CocoaPods](https://cocoapods.org) to import required API Gateway libraries and other dependent Amazon Mobile SDK components. You must update the `Podfile` to import the SDKs into your app's Xcode project. The unarchived SDK folder also contains a `generated-src` folder that contains the source code of the generated SDK of your API.

1. Launch Xcode and create a new iOS Objective-C project. Make a note of the project's target. You will need to set it in the `Podfile`.

    

1. To import the Amazon Mobile SDK for iOS into the Xcode project by using CocoaPods, do the following:

   1. Install CocoaPods by running the following command in a terminal window:

      ```
      sudo gem install cocoapods
      pod setup
      ```

   1. Copy the `Podfile` file from the extracted SDK folder into the same directory containing your Xcode project file. Replace the following block:

      ```
      target '<YourXcodeTarget>' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      with your project's target name: 

      ```
      target 'app_objc_simple_calc' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      If your Xcode project already contains a file named `Podfile`, add the following line of code to it:

      ```
      pod 'AWSAPIGateway', '~> 2.4.7'
      ```

   1. Open a terminal window and run the following command:

      ```
      pod install
      ```

      This installs the API Gateway component and other dependent Amazon Mobile SDK components.

   1. Close the Xcode project and then open the `.xcworkspace` file to relaunch Xcode.

   1. Add all of the `.h` and `.m` files from the extracted SDK's `generated-src` directory into your Xcode project.

       

   To import the Amazon Mobile SDK for iOS Objective-C into your project by explicitly downloading Amazon Mobile SDK or using [Carthage](https://github.com/Carthage/Carthage#installing-carthage), follow the instructions in the *README.md* file. Be sure to use only one of these options to import the Amazon Mobile SDK.

### Call API methods using the iOS SDK generated by API Gateway in an Objective-C project


When you generated the SDK with the prefix of `SIMPLE_CALC` for this [SimpleCalc API](simple-calc-lambda-api.md) with two models for input (`Input`) and output (`Result`) of the methods, in the SDK, the resulting API client class becomes `SIMPLE_CALCSimpleCalcClient` and the corresponding data classes are `SIMPLE_CALCInput` and `SIMPLE_CALCResult`, respectively. The API requests and responses are mapped to the SDK methods as follows:
+ The API request of

  ```
  GET /?a=...&b=...&op=...
  ```

  becomes the SDK method of

  ```
  (AWSTask *)rootGet:(NSString *)op a:(NSString *)a b:(NSString *)b
  ```

  The `AWSTask.result` property is of the `SIMPLE_CALCResult` type if the `Result` model was added to the method response. Otherwise, the property is of the `NSDictionary` type.
+ This API request of

  ```
  POST /
      
  {
     "a": "Number",
     "b": "Number",
     "op": "String"
  }
  ```

  becomes the SDK method of

  ```
  (AWSTask *)rootPost:(SIMPLE_CALCInput *)body
  ```
+ The API request of

  ```
  GET /{a}/{b}/{op}
  ```

  becomes the SDK method of

  ```
  (AWSTask *)aBOpGet:(NSString *)a b:(NSString *)b op:(NSString *)op
  ```

The following procedure describes how to call the API methods in Objective-C app source code; for example, as part of the `viewDidLoad` delegate in a `ViewController.m` file.

**To call the API through the iOS SDK generated by API Gateway**

1. Import the API client class header file to make the API client class callable in the app:

   ```
   #import "SIMPLE_CALCSimpleCalc.h"
   ```

   The `#import` statement also imports `SIMPLE_CALCInput.h` and `SIMPLE_CALCResult.h` for the two model classes.

1. Instantiate the API client class:

   ```
   SIMPLE_CALCSimpleCalcClient *apiInstance = [SIMPLE_CALCSimpleCalcClient defaultClient];
   ```

   To use Amazon Cognito with the API, set the `defaultServiceConfiguration` property on the default `AWSServiceManager` object, as shown in the following, before calling the `defaultClient` method to create the API client object (shown in the preceding example):

   ```
   AWSCognitoCredentialsProvider *creds = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:your_cognito_pool_id];
   AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:creds];
   AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
   ```

1. Call the `GET /?a=1&b=2&op=+` method to perform `1+2`:

   ```
   [[apiInstance rootGet: @"+" a:@"1" b:@"2"] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
       _textField1.text = [self handleApiResponse:task];
       return nil;
   }];
   ```

   where the helper function `handleApiResponse:task` formats the result as a string to be displayed in a text field (`_textField1`).

   ```
   - (NSString *)handleApiResponse:(AWSTask *)task {
       if (task.error != nil) {
           return [NSString stringWithFormat: @"Error: %@", task.error.description];
       } else if (task.result != nil && [task.result isKindOfClass:[SIMPLE_CALCResult class]]) {
           return [NSString stringWithFormat:@"%@ %@ %@ = %@\n",task.result.input.a, task.result.input.op, task.result.input.b, task.result.output.c];
       }
       return nil;
   }
   ```

   The resulting display is `1 + 2 = 3`.

1. Call the `POST /` with a payload to perform `1-2`:

   ```
   SIMPLE_CALCInput *input = [[SIMPLE_CALCInput alloc] init];
       input.a = [NSNumber numberWithInt:1];
       input.b = [NSNumber numberWithInt:2];
       input.op = @"-";
       [[apiInstance rootPost:input] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
           _textField2.text = [self handleApiResponse:task];
           return nil;
       }];
   ```

   The resulting display is `1 - 2 = -1`.

1. Call the `GET /{a}/{b}/{op}` to perform `1/2`:

   ```
   [[apiInstance aBOpGet:@"1" b:@"2" op:@"div"] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
       _textField3.text = [self handleApiResponse:task];
       return nil;
   }];
   ```

   The resulting display is `1 div 2 = 0.5`. Here, `div` is used in place of `/` because the [simple Lambda function](simple-calc-nodejs-lambda-function.md) in the backend does not handle URL encoded path variables.

## Use generated iOS SDK (Swift) to call API
Use generated iOS SDK (Swift) to call API

Before beginning the following procedure, you must complete the steps in [Generate SDKs for REST APIs in API Gateway](how-to-generate-sdk.md) for iOS in Swift and download the .zip file of the generated SDK.

**Topics**
+ [

### Install Amazon mobile SDK and API Gateway-generated SDK in a Swift project
](#use-sdk-ios-swift-install-sdk)
+ [

### Call API methods through the iOS SDK generated by API Gateway in a Swift project
](#use-sdk-ios-swift-call-api)

### Install Amazon mobile SDK and API Gateway-generated SDK in a Swift project


The following procedure describes how to install the SDK.

**To install and use an iOS SDK generated by API Gateway in Swift**

1. Extract the contents of the API Gateway-generated .zip file you downloaded earlier. Using the [SimpleCalc API](simple-calc-lambda-api.md), you may want to rename the unzipped SDK folder to something like **sdk\$1swift\$1simple\$1calc**. In this SDK folder there is a `README.md` file and a `Podfile` file. The `README.md` file contains the instructions to install and use the SDK. This tutorial provides details about these instructions. The installation leverages [CocoaPods](https://cocoapods.org) to import required Amazon Mobile SDK components. You must update the `Podfile` to import the SDKs into your Swift app's Xcode project. The unarchived SDK folder also contains a `generated-src` folder that contains the source code of the generated SDK of your API.

1. Launch Xcode and create a new iOS Swift project. Make a note of the project's target. You will need to set it in the `Podfile`.

    

1. To import the required Amazon Mobile SDK components into the Xcode project by using CocoaPods, do the following:

   1. If it is not installed, install CocoaPods by running the following command in a terminal window:

      ```
      sudo gem install cocoapods
      pod setup
      ```

   1. Copy the `Podfile` file from the extracted SDK folder into the same directory containing your Xcode project file. Replace the following block:

      ```
      target '<YourXcodeTarget>' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      with your project's target name as shown: 

      ```
      target 'app_swift_simple_calc' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      If your Xcode project already contains a `Podfile` with the correct target, you can simply add the following line of code to the `do ... end` loop:

      ```
      pod 'AWSAPIGateway', '~> 2.4.7'
      ```

   1. Open a terminal window and run the following command in the app directory:

      ```
      pod install
      ```

      This installs the API Gateway component and any dependent Amazon Mobile SDK components into the app's project.

   1. Close the Xcode project and then open the `*.xcworkspace` file to relaunch Xcode.

   1. Add all of the SDK's header files (`.h`) and Swift source code files (`.swift`) from the extracted `generated-src` directory to your Xcode project.

       

   1. To enable calling the Objective-C libraries of the Amazon Mobile SDK from your Swift code project, set the `Bridging_Header.h` file path on the **Objective-C Bridging Header** property under the **Swift Compiler - General** setting of your Xcode project configuration: 

       
**Tip**  
You can type **bridging** in the search box of Xcode to locate the **Objective-C Bridging Header** property.

   1. Build the Xcode project to verify that it is properly configured before proceeding further. If your Xcode uses a more recent version of Swift than the one supported for the Amazon Mobile SDK, you will get Swift compiler errors. In this case, set the **Use Legacy Swift Language Version** property to **Yes** under the **Swift Compiler - Version** setting:

       

   To import the Amazon Mobile SDK for iOS in Swift into your project by explicitly downloading the Amazon Mobile SDK or using [Carthage](https://github.com/Carthage/Carthage#installing-carthage), follow the instructions in the `README.md` file that comes with the SDK package. Be sure to use only one of these options to import the Amazon Mobile SDK.

### Call API methods through the iOS SDK generated by API Gateway in a Swift project


When you generated the SDK with the prefix of `SIMPLE_CALC` for this [SimpleCalc API](simple-calc-lambda-api.md) with two models to describe the input (`Input`) and output (`Result`) of the API's requests and responses, in the SDK, the resulting API client class becomes `SIMPLE_CALCSimpleCalcClient` and the corresponding data classes are `SIMPLE_CALCInput` and `SIMPLE_CALCResult`, respectively. The API requests and responses are mapped to the SDK methods as follows: 
+ The API request of

  ```
  GET /?a=...&b=...&op=...
  ```

  becomes the SDK method of

  ```
  public func rootGet(op: String?, a: String?, b: String?) -> AWSTask
  ```

  The `AWSTask.result` property is of the `SIMPLE_CALCResult` type if the `Result` model was added to the method response. Otherwise, it is of the `NSDictionary` type.
+ This API request of

  ```
  POST /
      
  {
     "a": "Number",
     "b": "Number",
     "op": "String"
  }
  ```

  becomes the SDK method of

  ```
  public func rootPost(body: SIMPLE_CALCInput) -> AWSTask
  ```
+ The API request of

  ```
  GET /{a}/{b}/{op}
  ```

  becomes the SDK method of

  ```
  public func aBOpGet(a: String, b: String, op: String) -> AWSTask
  ```

The following procedure describes how to call the API methods in Swift app source code; for example, as part of the `viewDidLoad()` delegate in a `ViewController.m` file.

**To call the API through the iOS SDK generated by API Gateway**

1. Instantiate the API client class:

   ```
   let client = SIMPLE_CALCSimpleCalcClient.default()
   ```

   To use Amazon Cognito with the API, set a default Amazon service configuration (shown following) before getting the `default` method (shown previously):

   ```
   let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityPoolId: "my_pool_id")        
   let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)        
   AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
   ```

1. Call the `GET /?a=1&b=2&op=+` method to perform `1+2`:

   ```
   client.rootGet("+", a: "1", b:"2").continueWithBlock {(task: AWSTask) -> AnyObject? in
       self.showResult(task)
       return nil
   }
   ```

   where the helper function `self.showResult(task)` prints the result or error to the console; for example: 

   ```
   func showResult(task: AWSTask) {
       if let error = task.error {
           print("Error: \(error)")
       } else if let result = task.result {
           if result is SIMPLE_CALCResult {
               let res = result as! SIMPLE_CALCResult
               print(String(format:"%@ %@ %@ = %@", res.input!.a!, res.input!.op!, res.input!.b!, res.output!.c!))
           } else if result is NSDictionary {
               let res = result as! NSDictionary
               print("NSDictionary: \(res)")
           }
       }
   }
   ```

   In a production app, you can display the result or error in a text field. The resulting display is `1 + 2 = 3`.

1. Call the `POST /` with a payload to perform `1-2`:

   ```
   let body = SIMPLE_CALCInput()
   body.a=1
   body.b=2
   body.op="-"
   client.rootPost(body).continueWithBlock {(task: AWSTask) -> AnyObject? in
       self.showResult(task)
       return nil
   }
   ```

   The resultant display is `1 - 2 = -1`.

1. Call the `GET /{a}/{b}/{op}` to perform `1/2`:

   ```
   client.aBOpGet("1", b:"2", op:"div").continueWithBlock {(task: AWSTask) -> AnyObject? in
       self.showResult(task)
       return nil
   }
   ```

   The resulting display is `1 div 2 = 0.5`. Here, `div` is used in place of `/` because the [simple Lambda function](simple-calc-nodejs-lambda-function.md) in the backend does not handle URL encoded path variables.

# Develop REST APIs using OpenAPI in API Gateway
OpenAPI

You can use API Gateway to import a REST API from an external definition file into API Gateway. Currently, API Gateway supports [OpenAPI v2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) and [OpenAPI v3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.1.md) definition files, with exceptions listed in [Amazon API Gateway important notes for REST APIs](api-gateway-known-issues.md#api-gateway-known-issues-rest-apis). You can update an API by overwriting it with a new definition, or you can merge a definition with an existing API. You specify the options by using a `mode` query parameter in the request URL. 

For a tutorial on using the Import API feature from the API Gateway console, see [Tutorial: Create a REST API by importing an example](api-gateway-create-api-from-example.md).

**Topics**
+ [

# Import an edge-optimized API into API Gateway
](import-edge-optimized-api.md)
+ [

# Import a Regional API into API Gateway
](import-export-api-endpoints.md)
+ [

# Import an OpenAPI file to update an existing API definition
](api-gateway-import-api-update.md)
+ [

# Set the OpenAPI `basePath` property
](api-gateway-import-api-basePath.md)
+ [

# Amazon variables for OpenAPI import
](import-api-aws-variables.md)
+ [

# Errors and warnings from importing your API into API Gateway
](api-gateway-import-api-errors-warnings.md)
+ [

# Export a REST API from API Gateway
](api-gateway-export-api.md)

# Import an edge-optimized API into API Gateway
Import an edge-optimized API

You can import an API's OpenAPI definition file to create a new edge-optimized API by specifying the `EDGE` endpoint type as an additional input, besides the OpenAPI file, to the import operation. You can do so using the API Gateway console, Amazon CLI, or an Amazon SDK.

For a tutorial on using the Import API feature from the API Gateway console, see [Tutorial: Create a REST API by importing an example](api-gateway-create-api-from-example.md).

**Topics**
+ [

## Import an edge-optimized API using the API Gateway console
](#import-edge-optimized-api-with-console)
+ [

## Import an edge-optimized API using the Amazon CLI
](#import-edge-optimized-api-with-awscli)

## Import an edge-optimized API using the API Gateway console


To import an edge-optimized API using the API Gateway console, do the following:

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose **Create API**.

1. Under **REST API**, choose **Import**.

1.  Copy an API's OpenAPI definition and paste it into the code editor, or choose **Choose file** to load an OpenAPI file from a local drive.

1.  For **API endpoint type**, select **Edge-optimized**.

1.  Choose **Create API** to start importing the OpenAPI definitions.

## Import an edge-optimized API using the Amazon CLI


The following [import-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/import-rest-api.html) command imports an API from an OpenAPI definition file to create a new edge-optimized API:

```
aws apigateway import-rest-api \
    --fail-on-warnings \
    --body 'file://path/to/API_OpenAPI_template.json'
```

or with an explicit specification of the `endpointConfigurationTypes` query string parameter to `EDGE`: 

```
aws apigateway import-rest-api \
    --parameters endpointConfigurationTypes=EDGE \
    --fail-on-warnings \
    --body 'file://path/to/API_OpenAPI_template.json'
```



# Import a Regional API into API Gateway
Import a Regional API

When importing an API, you can choose the regional endpoint configuration for the API. You can use the API Gateway console, the Amazon CLI, or an Amazon SDK.

When you export an API, the API endpoint configuration is not included in the exported API definitions.

For a tutorial on using the Import API feature from the API Gateway console, see [Tutorial: Create a REST API by importing an example](api-gateway-create-api-from-example.md).

**Topics**
+ [

## Import a regional API using the API Gateway console
](#import-regional-api-with-console)
+ [

## Import a regional API using the Amazon CLI
](#import-regional-api-with-awscli)

## Import a regional API using the API Gateway console


To import an API of a regional endpoint using the API Gateway console, do the following:

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose **Create API**.

1. Under **REST API**, choose **Import**.

1.  Copy an API's OpenAPI definition and paste it into the code editor, or choose **Choose file** to load an OpenAPI file from a local drive.

1. For **API endpoint type**, select **Regional**.

1.  Choose **Create API** to start importing the OpenAPI definitions.

## Import a regional API using the Amazon CLI


The following [import-rest-api](https://docs.amazonaws.cn/cli/latest/reference/apigateway/import-rest-api.html) command imports an OpenAPI definition file and sets the endpoint type to Regional:

```
aws apigateway import-rest-api \
    --parameters endpointConfigurationTypes=REGIONAL \
    --fail-on-warnings \
    --body 'file://path/to/API_OpenAPI_template.json'
```

# Import an OpenAPI file to update an existing API definition


 You can import API definitions only to update an existing API, without changing its endpoint configuration, as well as stages and stage variables, or references to API keys. 

 The import-to-update operation can occur in two modes: merge or overwrite. 

When an API (`A`) is merged into another (`B`), the resulting API retains the definitions of both `A` and `B` if the two APIs do not share any conflicting definitions. When conflicts arise, the method definitions of the merging API (`A`) overrides the corresponding method definitions of the merged API (`B`). For example, suppose `B` has declared the following methods to return `200` and `206` responses:

```
GET /a
POST /a
```

and `A` declares the following method to return `200` and `400` responses:

```
GET /a
```

When `A` is merged into `B`, the resulting API yields the following methods:

```
GET /a
```

which returns `200` and `400` responses, and 

```
POST /a
```

which returns `200` and `206` responses.

Merging an API is useful when you have decomposed your external API definitions into multiple, smaller parts and only want to apply changes from one of those parts at a time. For example, this might occur if multiple teams are responsible for different parts of an API and have changes available at different rates. In this mode, items from the existing API that aren't specifically defined in the imported definition are left alone. 

When an API (`A`) overwrites another API (`B`), the resulting API takes the definitions of the overwriting API (`A`). Overwriting an API is useful when an external API definition contains the complete definition of an API. In this mode, items from an existing API that aren't specifically defined in the imported definition are deleted. 

 To merge an API, submit a `PUT` request to `https://apigateway.<region>.amazonaws.com/restapis/<restapi_id>?mode=merge`. The `restapi_id` path parameter value specifies the API to which the supplied API definition will be merged. 

 The following code snippet shows an example of the `PUT` request to merge an OpenAPI API definition in JSON, as the payload, with the specified API already in API Gateway. 

```
PUT /restapis/<restapi_id>?mode=merge
Host:apigateway.<region>.amazonaws.com
Content-Type: application/json
Content-Length: ...

An OpenAPI API definition in JSON
```

 The merging update operation takes two complete API definitions and merges them together. For a small and incremental change, you can use the [resource update](https://docs.amazonaws.cn/apigateway/latest/api/API_UpdateResource.html) operation. 

 To overwrite an API, submit a `PUT` request to `https://apigateway.<region>.amazonaws.com/restapis/<restapi_id>?mode=overwrite`. The `restapi_id` path parameter specifies the API that will be overwritten with the supplied API definitions. 

 The following code snippet shows an example of an overwriting request with the payload of a JSON-formatted OpenAPI definition: 

```
PUT /restapis/<restapi_id>?mode=overwrite
Host:apigateway.<region>.amazonaws.com
Content-Type: application/json
Content-Length: ...

An OpenAPI API definition in JSON
```

 When the `mode` query parameter isn't specified, merge is assumed.

**Note**  
 The `PUT` operations are idempotent, but not atomic. That means if a system error occurs part way through processing, the API can end up in a bad state. However, repeating the operation successfully puts the API into the same final state as if the first operation had succeeded. 

# Set the OpenAPI `basePath` property


In [OpenAPI 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md), you can use the `basePath` property to provide one or more path parts that precede each path defined in the `paths` property. Because API Gateway has several ways to express a resource's path, the Import API feature provides the following options for interpreting the `basePath` property during import: ignore, prepend, and split.

In [https://swagger.io/docs/specification/api-host-and-base-path/](https://swagger.io/docs/specification/api-host-and-base-path/), `basePath` is no longer a top-level property. Instead, API Gateway uses a [server variable](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#serverVariableObject) as a convention. The Import API feature provides the same options for interpreting the base path during import. The base path is identified as follows:
+ If the API doesn't contain any `basePath` variables, the Import API feature checks the `server.url` string to see if it contains a path beyond `"/"`. If it does, that path is used as the base path.
+ If the API contains only one `basePath` variable, the Import API feature uses it as the base path, even if it's not referenced in the `server.url`.
+ If the API contains multiple `basePath` variables, the Import API feature uses only the first one as the base path.

## Ignore


If the OpenAPI file has a `basePath` value of `/a/b/c` and the `paths` property contains `/e` and `/f`, the following `POST` or `PUT` request: 

```
POST /restapis?mode=import&basepath=ignore
```



```
PUT /restapis/api_id?basepath=ignore
```

 results in the following resources in the API: 
+ `/`
+ `/e`
+ `/f`

 The effect is to treat the `basePath` as if it was not present, and all of the declared API resources are served relative to the host. This can be used, for example, when you have a custom domain name with an API mapping that doesn't include a *Base Path* and a *Stage* value that refers to your production stage. 

**Note**  
 API Gateway automatically creates a root resource for you, even if it isn't explicitly declared in your definition file. 

 When unspecified, `basePath` takes `ignore` by default. 

## Prepend


 If the OpenAPI file has a `basePath` value of `/a/b/c` and the `paths` property contains `/e` and `/f`, the following `POST` or `PUT` request: 

```
POST /restapis?mode=import&basepath=prepend
```



```
PUT /restapis/api_id?basepath=prepend
```

 results in the following resources in the API: 
+ `/`
+ `/a`
+ `/a/b`
+ `/a/b/c`
+ `/a/b/c/e`
+ `/a/b/c/f`

 The effect is to treat the `basePath` as specifying additional resources (without methods) and to add them to the declared resource set. This can be used, for example, when different teams are responsible for different parts of an API and the `basePath` could reference the path location for each team's API part. 

**Note**  
 API Gateway automatically creates intermediate resources for you, even if they aren't explicitly declared in your definition. 

## Split


 If the OpenAPI file has a `basePath` value of `/a/b/c` and the `paths` property contains `/e` and `/f`, the following `POST` or `PUT` request: 

```
POST /restapis?mode=import&basepath=split
```



```
PUT /restapis/api_id?basepath=split
```

 results in the following resources in the API: 
+ `/`
+ `/b`
+ `/b/c`
+ `/b/c/e`
+ `/b/c/f`

 The effect is to treat top-most path part, `/a`, as the beginning of each resource's path, and to create additional (no method) resources within the API itself. This could, for example, be used when `a` is a stage name that you want to expose as part of your API. 

# Amazon variables for OpenAPI import
Amazon variables

You can use the following Amazon variables in OpenAPI definitions. API Gateway resolves the variables when the API is imported. To specify a variable, use `${variable-name}`. The following table describes the available Amazon variables. 


| Variable name | Description | 
| --- | --- | 
| AWS::AccountId | The Amazon account ID that imports the API. For example, 123456789012. | 
| AWS::Partition | The Amazon partition in which the API is imported. For standard Amazon Regions, the partition is aws. | 
| AWS::Region | The Amazon Region in which the API is imported. For example, us-west-2. | 

## Amazon variables example


The following example uses Amazon variables to specify an Amazon Lambda function for an integration.

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

```
openapi: "3.0.1"
info:
  title: "tasks-api"
  version: "v1.0"
paths:
  /:
    get:
      summary: List tasks
      description: Returns a list of tasks
      responses:
        200:
          description: "OK"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Task"
        500:
          description: "Internal Server Error"
          content: {}
      x-amazon-apigateway-integration:
        uri:
          arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:LambdaFunctionName/invocations
        responses:
          default:
            statusCode: "200"
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
        contentHandling: "CONVERT_TO_TEXT"
        type: "aws_proxy"
components:
  schemas:
    Task:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
```

------

# Errors and warnings from importing your API into API Gateway


When you import your external definition file into API Gateway, API Gateway might generate warnings and errors. The following sections discuss the errors and warnings that might occur during import.

## Errors during import


 During the import, errors can be generated for major issues like an invalid OpenAPI document. Errors are returned as exceptions (for example, `BadRequestException`) in an unsuccessful response. When an error occurs, the new API definition is discarded and no change is made to the existing API. 

## Warnings during import


 During the import, warnings can be generated for minor issues like a missing model reference. If a warning occurs, the operation will continue if the `failonwarnings=false` query expression is appended to the request URL. Otherwise, the updates will be rolled back. By default, `failonwarnings` is set to `false`. In such cases, warnings are returned as a field in the resulting [RestApi](https://docs.amazonaws.cn/apigateway/latest/api/API_RestApi.html) resource. Otherwise, warnings are returned as a message in the exception. 

# Export a REST API from API Gateway
Export a REST API

 Once you created and configured a REST API in API Gateway, using the API Gateway console or otherwise, you can export it to an OpenAPI file using the API Gateway Export API, which is part of the Amazon API Gateway Control Service. To use the API Gateway Export API, you need to sign your API requests. For more information about signing requests, see [Signing Amazon API requests](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_aws-signing.html) in the *IAM User Guide*. You have options to include the API Gateway integration extensions, as well as the [Postman](https://www.postman.com) extensions, in the exported OpenAPI definition file. 

**Note**  
When exporting the API using the Amazon CLI, be sure to include the extensions parameter as shown in the following example, to ensure that the `x-amazon-apigateway-request-validator` extension is included:  

```
aws apigateway get-export --parameters extensions='apigateway' --rest-api-id abcdefg123 --stage-name dev --export-type swagger latestswagger2.json
```

 You cannot export an API if its payloads are not of the `application/json` type. If you try, you will get an error response stating that JSON body models are not found. 

## Request to export a REST API


 With the Export API, you export an existing REST API by submitting a GET request, specifying the to-be-exported API as part of URL paths. The request URL is of the following format: 

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

```
 https://<host>/restapis/<restapi_id>/stages/<stage_name>/exports/oas30
```

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

```
 https://<host>/restapis/<restapi_id>/stages/<stage_name>/exports/swagger
```

------

 You can append the `extensions` query string to specify whether to include API Gateway extensions (with the `integration` value) or Postman extensions (with the `postman` value). 

 In addition, you can set the `Accept` header to `application/json` or `application/yaml` to receive the API definition output in JSON or YAML format, respectively. 

 For more information about submitting GET requests using the API Gateway Export API, see [GetExport](https://docs.amazonaws.cn/apigateway/latest/api/API_GetExport.html). 

**Note**  
 If you define models in your API, they must be for the content type of "application/json" for API Gateway to export the model. Otherwise, API Gateway throws an exception with the "Only found non-JSON body models for ..." error message.   
 Models must contain properties or be defined as a particular JSONSchema type. 

## Download REST API OpenAPI definition in JSON


To export and download a REST API in OpenAPI definitions in JSON format:

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

------

 Here, `<region>` could be, for example, `us-east-1`. For all the regions where API Gateway is available, see [Regions and Endpoints](https://docs.amazonaws.cn/general/latest/gr/rande.html#apigateway_region). 

## Download REST API OpenAPI definition in YAML


To export and download a REST API in OpenAPI definitions in YAML format:

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

------

## Download REST API OpenAPI definition with Postman extensions in JSON


To export and download a REST API in OpenAPI definitions with Postman in JSON format:

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30?extensions=postman
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger?extensions=postman
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

------

## Download REST API OpenAPI definition with API Gateway integration in YAML


To export and download a REST API in OpenAPI definitions with API Gateway integration in YAML format:

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30?extensions=integrations
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger?extensions=integrations
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

------

## Export REST API using the API Gateway console


After [deploying your REST API to a stage](set-up-deployments.md#create-deployment), you can proceed to export the API in the stage to an OpenAPI file using the API Gateway console.

 In the **Stages** pane in the API Gateway console, choose **Stage actions**, **Export**.

Specify an **API specification type**, **Format**, and **Extensions** to download your API's OpenAPI definition. 