Skip to content

API Gateway fails to get a proper response body from my Lambda function

0

Hello community.

I am using Terraform to create a REST API Gateway with a Lambda function that retrieves values from a DynamoDB table. I made the API via the console, and it worked fine. With Terraform, it is not working as expected. I am using a JSON request body that works if I test directly in Lambda console but through API gateway, it fails with Method completed with status: 502.

My function is

import boto3 # type: ignore

table_name = "count-table"

# Create the DynamoDB resource
dynamo = boto3.resource('dynamodb').Table(table_name)

# Function to retrieve the number of visitis
def read(payload):
    return dynamo.get_item(Key=payload['Key'])


operations = {'read': read}

#Lambda handler that expects a JSON object to trigger the function

def lambda_handler(event, context):
    operation = event['operation']
    payload = event['payload']
    
    if operation in operations:
        return operations[operation](payload)
        
    else:
        raise ValueError(f'Unrecognized operation "{operation}"')

Expected output Response: { "Item": { "id": "visitors", "number": 1 },

Checking the AWS docs, it says that I need to change my function to format the output, Is there another way to fix it?

3 Answers
1

The 502 error occurs because API Gateway expects a specific response format. You need to modify your Lambda function to return a properly formatted response:

import boto3
import json

table_name = "count-table"
dynamo = boto3.resource('dynamodb').Table(table_name)

def read(payload):
    return dynamo.get_item(Key=payload['Key'])

operations = {'read': read}

def lambda_handler(event, context):
    try:
        operation = event['operation']
        payload = event['payload']
        
        if operation in operations:
            result = operations[operation](payload)
            return {
                'statusCode': 200,
                'headers': {
                    'Content-Type': 'application/json'
                },
                'body': json.dumps(result)
            }
    except Exception as e:
        return {
            'statusCode': 500,
            'headers': {
                'Content-Type': 'application/json'
            },
            'body': json.dumps({'error': str(e)})
        }

Key points:

  1. The response must include statusCode, headers, and body
  2. The body must be a JSON-formatted string
  3. Include error handling to return proper error responses

For more details, see AWS documentation on Lambda integration responses.

AWS

answered a year ago

0

The 502 error you're experiencing is because your Lambda function isn't returning a response in the format that API Gateway expects. When using Lambda proxy integration with API Gateway, your function must return a specific structure that includes statusCode, headers, and body fields.

Currently, your function is returning the raw DynamoDB response, which doesn't match this required format. You need to modify your Lambda function to properly format the response.

Here's how you can modify your Lambda handler:

import boto3 # type: ignore
import json

table_name = "count-table"

# Create the DynamoDB resource
dynamo = boto3.resource('dynamodb').Table(table_name)

# Function to retrieve the number of visits
def read(payload):
return dynamo.get_item(Key=payload['Key'])

operations = {'read': read}

# Lambda handler that expects a JSON object to trigger the function
def lambda_handler(event, context):
try:
operation = event['operation']
payload = event['payload']

if operation in operations:
result = operations[operation](payload)

# Format the response for API Gateway
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps(result)
}
else:
return {
'statusCode': 400,
'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps({'error': f'Unrecognized operation "{operation}"'})
}
except Exception as e:
return {
'statusCode': 500,
'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps({'error': str(e)})
}

This modification ensures your Lambda function returns a response in the format that API Gateway expects, with the proper statusCode, headers, and a JSON-stringified body. The actual DynamoDB response will be contained within the body field of your API response.

When testing directly in the Lambda console, you see the raw response because the console doesn't require this specific format, but API Gateway does require it for proper integration.
Sources
How Does API Gateway Handle the Response Returned by a Lambda Function? | AWS re:Post
Create AWS Lambda proxy integrations for HTTP APIs in API Gateway - Amazon API Gateway
Community | Demystifying AWS Lambda: Deep Dive into Serverless Computing

answered a year ago

0

Hello! Thank you for the answer, when I curl returned the error allan@ALLAN-Z:~/learn-lambda-apigw-terraform$ curl https://l77ja9xmi0.execute-api.us-west-2.amazonaws.com/dev/dynamodb -H "Content-Type: application/json" -d '{"operation": "read", "payload": {"Key": {"id": "visitors"}}}' {"error": "'operation'"}

I tested Lambda isolated and received the error "Object of type Decimal is not JSON serializable". So I tried using import simplejson as json and returned this

Response:
{
  "statusCode": 200,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": "{\"Item\": {\"id\": \"visitors\", \"number\": 1}, \"ResponseMetadata\": {\"RequestId\": \"GKNC3ETVJ63HNJED3SVTJNKG53VV4KQNSO5AEMVJF66Q9ASUAAJG\", \"HTTPStatusCode\": 200, \"HTTPHeaders\": {\"server\": \"Server\", \"date\": \"Tue, 03 Jun 2025 20:53:17 GMT\", \"content-type\": \"application/x-amz-json-1.0\", \"content-length\": \"51\", \"connection\": \"keep-alive\", \"x-amzn-requestid\": \"GKNC3ETVJ63HNJED3SVTJNKG53VV4KQNSO5AEMVJF66Q9ASUAAJG\", \"x-amz-crc32\": \"3824588171\"}, \"RetryAttempts\": 0}}"
}

But testing from the API Gateway shows this error

Tue Jun 03 20:54:41 UTC 2025 : Endpoint response body before transformations: {"statusCode": 500, "headers": {"Content-Type": "application/json"}, "body": "{"error": "'operation'"}"} Tue Jun 03 20:54:41 UTC 2025 : Method response body after transformations: {"error": "'operation'"}

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.