How do I map the response status codes for API Gateway integrations in REST APIs?

Last updated: 2022-09-30

Why is AWS Lambda returning 200 OK status code responses in REST APIs?

How do I map the status codes returned by REST APIs in Amazon API Gateway?

-or-

How do I map status codes in REST APIs?

Resolution

When you want to override your backend response status codes, use API Gateway mapping templates or regular expressions to map the status codes. You can do this in proxy and non-proxy integrations with REST API.

Proxy and non-proxy integrations are used to map response status codes in REST API. When there’s a proxy response, API Gateway receives the status codes as they’re sent by the backend. In a Lambda proxy integration, API Gateway requires the backend Lambda function to return the following output in JSON format:

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode, 
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": “…”65411
}

In a proxy integration with a Lambda function, a status code is passed directly to API Gateway from a backend Lambda function. A status code can’t be passed directly from the Lambda function in a non-proxy integration.

When API Gateway successfully invokes a Lambda function, the default response status code is 200. Status codes are also returned when Lambda experiences errors. You can customize API Gateway response codes. Use a non-proxy integration and a mapping template when you need to create a custom response code.

Configuring a response method with custom code

Follow these steps to configure a method to respond with custom response code from API Gateway:

1.    In the API Gateway console, create a public REST API.

2.    Create a resource and a method for the resource.

3.    Set up a method response that includes the status code that you want API Gateway to return.

4.    Configure a Lambda integration response.

  • For Lambda Error Regex, provide the regular expression pattern for the error message that's returned by the Lambda function.
    Note: You can also find the HTTP error regex for HTTP responses.
  • For the method response status, provide the status code that must be returned by API Gateway.
  • Choose an option for Content Handling to set how the response body is handled before the response is sent to the client.
  • Make sure that the default pattern of the status code is set to 200.

5.    After you finish configuring your integration response, save, test, and deploy your changes.

Mapping status codes to static values

For API Gateway to capture a group of status codes returned from your backend, map the status codes to static values:

1.    Go to the resource that has the status code you want to change.

2.    Set up a method response to return 400 as the API Gateway response code.

3.    Go back to the resource configurations and set up an integration response.

4.    The values in HTTP status regex capture the status returned by your backend. The status is then mapped to the response code defined in Step 2.

When HTTP status regex has a default value of "-" and is mapped to 200 as the method response status, all status codes are captured and returned by your backend map to 200. You can change the HTTP status regex values to 2\d{2} to capture all 2xx responses and map them to 200.

5.    Choose Add integration response to capture the other status codes.

For 4xx, in HTTP status regex, add 4\d{2}. For Method response status, choose 400. This was defined in Step 2.

6.    Deploy your API. When the API returns any 2xx status codes, they're mapped to the 200 status code. If your API returns any 4xx status codes, they’re mapped to the 400 status code.

Regular expressions can be formatted in multiple ways. For example:

  • .*([01][0-9][0-9]|2[0-4][0-9]|25[0-5]).* matches for status codes between 100-199, 200-249, or 250-255.
  • .*5\d\d.* matches a status code , such as 5xx.

The following example code is for testing a Lambda function:

def lambda_handler(event, context):
    if "error" not in event or event['error'] == "":
        return("Pass")
    elif event['error'] == 'sample 400':
        raise Exception({"errorMessage": "Error: Raising 400 from within the Lambda function","errorType": "Exception"})
    elif event['error'] == 'sample 500':
        raise Exception({"errorMessage": "Error: Raising 500 from within the Lambda function","errorType": "Exception"})
    else:
        return("Error Value in the json request should either be 400 or 500 to demonstrate")

In the example, the code checks if the error value sent from API Gateway is a 400 or 500 error. When it’s a 400 or 500 error, the Lambda code raises an exception with an error message. When API Gateway receives the response, the service checks if the error message matches any pattern configured in the integration response. API Gateway responds accordingly if the Lambda regex pattern is matched.

7.    After a successful configuration, the status codes can be tested using the API Gateway console.

Mapping status codes with mapping templates

The previous example uses regular expressions, but it can also use mapping templates. The following example overrides the 200 status code from the backend to apply the 400 status code:

1.    Create a Lambda function with following example code:

----------------------
def lambda_handler(event, context):
    # TODO implement print(event)
    return { 'statusCode': 200, 'body': "customerror" }
-----------------------

2.    Create an API with Lambda non-proxy integration by using the previous Lambda function for the backend.

3.    Follow steps 6-10 described in the Override an API's response status code with the API Gateway console tutorial.

In this example, use the following mapping template:

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

4.    Save, test, and deploy the API.