

# 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 AWS 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 AWS 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.aws.amazon.com/apigateway/latest/api/API_Integration.html](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) resource and an integration response by the [https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) resource of API Gateway. 

To set up an integration request, you create an [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html](https://docs.aws.amazon.com/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.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html](https://docs.aws.amazon.com/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 AWS 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.aws.amazon.com/apigateway/latest/api/API_Integration.html) resource of API Gateway and setting appropriate property values. You can do so using the API Gateway console, AWS CLI commands, an AWS 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.aws.amazon.com/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 AWS 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.aws.amazon.com/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 AWS 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 AWS integrations, you must also configure [credentials](https://docs.aws.amazon.com/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.aws.amazon.com/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 AWS service action, you have the AWS 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 AWS integration, where the integration endpoint corresponds to the [function-invoking action ](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html)of the Lambda service. 

Programmatically, you choose an integration type by setting the [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#type](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#type) property on the [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html](https://docs.aws.amazon.com/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 AWS 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 AWS 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 AWS 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.aws.amazon.com/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 AWS 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 `AWS` 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 AWS service integration


Use an AWS service integration to integrate your API directly with an AWS service. At the API level, this is the `AWS` 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 **AWS service**.

**To set up an AWS service integration**

1. In the **Resources** pane, choose **Create method**.

1. For **Method type**, select an HTTP method.

1. For **Integration type**, choose **AWS service**.

1. For **AWS Region**, choose the AWS Region you want this method to use to call the action.

1. For **AWS service**, choose the AWS service you want this method to call.

1.  For **AWS subdomain**, enter the subdomain used by the AWS service. Typically, you would leave this blank. Some AWS 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 AWS service you chose for **AWS 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 AWS service you chose for **AWS 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 AWS 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 AWS service you chose for **AWS service**.

   For the IAM role's trust relationship, specify the following, which enables API Gateway to take action on behalf of your AWS 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.aws.amazon.com/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 AWS 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 AWS 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 AWS CLI


In this section, we show how to set up an API with the Lambda proxy integration using the AWS 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 AWS CLI**

1. Use the following [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) command to create an API:

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   The output will look like the following:

   ```
   {
       "name": "HelloWorldProxy (AWS 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.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) command to create an API Gateway [Resource](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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 AWS 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 AWS CLI**

1. Use the following [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) command to create an API:

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   The output will look like the following:

   ```
   {
       "name": "HelloWorld (AWS 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.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) command to create an API Gateway [Resource](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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 AWS \
           --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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-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:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-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 CloudFormation


The following 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 AWS 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.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)` property of the [IntegrationResponse](https://docs.aws.amazon.com/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.aws.amazon.com/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 AWS CLI, call the [update-integration-response](https://docs.aws.amazon.com/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, AWS 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.aws.amazon.com/apigateway/latest/api/API_Method.html#requestParameters) property on a [Method](https://docs.aws.amazon.com/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.aws.amazon.com/apigateway/latest/api/API_Integration.html#requestParameters) property on the corresponding [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) resource to specify the parameter-to-parameter mappings. You also set the [requestTemplates](https://docs.aws.amazon.com/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.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseParameters) property on the [MethodResponse](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#responseParameters) property on the corresponding [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) resource to specify the parameter-to-parameter mappings. You also set the [responseTemplates](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/lambda/latest/dg/configuration-timeout.html).
+ Response streaming incurs a cost. For more information, see [API Gateway Pricing](https://aws.amazon.com/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).

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

**To create an HTTP proxy integration with payload response streaming**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/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**.

------
#### [ AWS 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.

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

**To update the response transfer mode for an HTTP proxy integration**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/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**.

------
#### [ AWS 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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  Yes. API Gateway streams your response.  | 
|  Stream  |  No  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  No. API Gateway invokes your Lambda function and return a 500 error response.  | 
|  Stream  |  Yes  |   [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Stream  |  No  |   [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Buffered  |  Yes  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Buffered  |  No  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  No. API Gateway doesn't support this integration configuration.  | 
|  Buffered  |  Yes  |   [Invoke](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.

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

**To create a Lambda proxy integration with payload response streaming**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/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.aws.amazon.com/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**.

------
#### [ AWS 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.

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

**To update the response transfer mode for a Lambda proxy integration**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/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**.

------
#### [ AWS CLI ]

1. Update your Lambda function to be streaming-enabled.

1. Use the following AWS 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.aws.amazon.com/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.aws.amazon.com/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.

![\[Access log variables for response streaming in API Gateway\]](http://docs.aws.amazon.com/apigateway/latest/developerguide/images/response-streaming-figure.png)


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 AWS 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.aws.amazon.com/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri](https://docs.aws.amazon.com/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 AWS 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.aws.amazon.com/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 AWS CLI


To create a VPC link V2, all resources involved must be owned by the same AWS account. The following [create-vpc-link](https://docs.aws.amazon.com/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 AWS CLI


The following [delete-vpc-link](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri](https://docs.aws.amazon.com/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.

------
#### [ AWS 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).

------
#### [ AWS CLI ]

The following [put-integration](https://docs.aws.amazon.com/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.aws.amazon.com/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.

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

**To update a private integration**

1. Sign in to the API Gateway console at [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/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.

------
#### [ AWS CLI ]

The following [update-integration](https://docs.aws.amazon.com/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.aws.amazon.com/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 AWS 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 AWS 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 AWS 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.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-listeners.html) and [target groups](https://docs.aws.amazon.com/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 AWS account.

**To create a Network Load Balancer for private integration using the API Gateway console**

1. Sign in to the AWS Management Console and open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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:elasticloadbalancing:us-east-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:apigateway:us-east-1::/vpclinks",
                   "arn:aws: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 AWS CLI (legacy)
Set up an API with private integrations using AWS 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 AWS 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 AWS 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 AWS CLI**

1. Use the following [create-vpc-link](https://docs.aws.amazon.com/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:elasticloadbalancing:us-east-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:elasticloadbalancing:us-east-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.aws.amazon.com/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.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) command to create an API Gateway [https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html](https://docs.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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-east-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.aws.amazon.com/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-east-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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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.aws.amazon.com/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-east-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** | 
| --- | --- | 
| us-east-1 | 392220576650 | 
| us-east-2 | 718770453195 | 
| us-west-1 | 968246515281 | 
| us-west-2 | 109351309407 | 
| ca-central-1 | 796887884028 | 
| eu-west-1 | 631144002099 | 
| eu-west-2 | 544388816663 | 
| eu-west-3 | 061510835048 | 
| eu-central-1 | 474240146802 | 
| eu-central-2 | 166639821150 | 
| eu-north-1 | 394634713161 | 
| eu-south-1 | 753362059629 | 
| eu-south-2 | 359345898052 | 
| ap-northeast-1 | 969236854626 | 
| ap-northeast-2 | 020402002396 | 
| ap-northeast-3 | 360671645888 | 
| ap-southeast-1 | 195145609632 | 
| ap-southeast-2 | 798376113853 | 
| ap-southeast-3 | 652364314486 | 
| ap-southeast-4 | 849137399833 | 
| ap-south-1 | 507069717855 | 
| ap-south-2 | 644042651268 | 
| ap-east-1 | 174803364771 | 
| sa-east-1 | 287228555773 | 
| me-south-1 | 855739686837 | 
| me-central-1 | 614065512851 | 

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