Search code examples
amazon-web-servicesaws-lambdaterraformamazon-dynamodbaws-api-gateway

I couldn't find error in AWS Lambda + DynamoDB Serverless


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.


Solution

  • 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"