I am currently studying AWS Lambda, Dynamodb, and API Gateway. I was developing a serverless API that simply creates a user and retrieves a user matching the ID. I tried a lot and searched, but I asked a question because of the 'Internal Server Error' that could not be resolved.
When I first discovered this error, I saw that it was because the return format was incorrect, so I used a return value that included isBase643Encoded, statusCode, headers, multiValueHeaders, and body, and used a string as well as body. However, when the error was not resolved and only statusCode and body existed among many attempts, INFO Success was confirmed to occur in CloudWatch Logs.
INFO Success {
'$metadata': {
httpStatusCode: 200,
requestId: 'requestId...',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
}
}
Below is the code of the lambda function that receives and processes the body value of name and password through POST method.
import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { DynamoDBDocumentClient, PutCommand } from '@aws-sdk/lib-dynamodb'
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'
import { v4 } from 'uuid'
const dynamo = new DynamoDBClient({})
const client = DynamoDBDocumentClient.from(dynamo)
export const handler = async (events: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const body = JSON.parse(events.body!)
const command = new PutCommand({
TableName: "DynamoUsers",
Item: {
id: v4(),
name: body.name,
password: body.password
},
})
await client.send(command)
try {
// await client.send(command)
// console.log('name', body.name)
return {
statusCode: 200,
body: "Hello World"
}
} catch (err) {
// console.log('err', err)
return {
statusCode: 200,
body: "Hello World"
}
}
}
I confirmed that returning the Hello, World string through the GET method without any db connection worked without any problem.
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'
export const handler = async (_: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
return {
statusCode: 200,
body: "Hello World"
}
}
API Gateway, Lambda functions, Lambda layers, etc. were written in Terraform. The code below is terraform code that handles the user-generated lambda function part.
# [POST] /users
resource "aws_apigatewayv2_integration" "users_create" {
api_id = aws_apigatewayv2_api.api_gateway.id
integration_uri = aws_lambda_function.users_create.invoke_arn
integration_type = "AWS_PROXY"
integration_method = "POST"
}
resource "aws_apigatewayv2_route" "users_create" {
api_id = aws_apigatewayv2_api.api_gateway.id
route_key = "POST /users"
target = "integrations/${aws_apigatewayv2_integration.users_create.id}"
}
resource "aws_lambda_permission" "api_gw_users_create" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.users_create.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_apigatewayv2_api.api_gateway.execution_arn}/*/*"
}
I'm sorry that I don't have much knowledge as I just started learning.
Read over the following troubleshooting article which should help you fix your issue:
https://repost.aws/knowledge-center/malformed-502-api-gateway
more here:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-troubleshooting-lambda.html
and here:
AWS lambda api gateway error "Malformed Lambda proxy response"