DrkStr
DrkStr

Reputation: 1932

Trouble with API Gateway to Lambda using CDK

I am using the Python CDK to deploy a Lambda function triggered by an API call. Here is my code:

app.py

#!/usr/bin/env python3
import os

from aws_cdk import core

from cvsg_app_bff.usermanagement import UserManagementStack

app = core.App()
UserManagementStack(app, "UserManagementStack")

app.synth()

My stack:

class UserManagementStack(core.Stack):

def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Lambda functions
    create_new_user: _lambda.Function = _lambda.Function(self, "newUserLambdaHandler",
                                                            runtime=_lambda.Runtime.PYTHON_3_8,
                                                            handler="usermanagement.create_new_user",
                                                            code=_lambda.Code.from_asset("lambda_functions")
                                                            )

    # API gateway setup
    user_apis = api_gw.LambdaRestApi(self, 'UserManagementAPIs', handler=create_new_user, proxy=False)

    user_apis.root.resource_for_path('user').add_method('POST', api_gw.LambdaIntegration(create_new_user))

File with the Lambda functions:

def format_return(status_code, response_body):
    response = {
        'statusCode': status_code,
        'body': response_body
    }
    print("Response: ", str(response))
    return response


def is_admin(event):
    # todo: not implemented yet!
    return True


def get_event_body(event):
    print(json.dumps(event))
    return json.loads(event["body"])


def create_new_user(event, context):
    request_body = get_event_body(event)
    if is_admin(event):
        return format_return(200, request_body)
    else:
        return format_return(403, "Not Unauthorised for this operation")

When I deploy and hit the endpoint, I get a 502 Bad Gateway response with this message

{
    "message": "Internal server error"
}

I had a look at the CloudWatch logs, and I can see the correct response printed in the format_response method but the response from the client hitting the endpoint is always 502.

How do I get the API gateway to return the correct response?

Upvotes: 1

Views: 901

Answers (1)

user16442705
user16442705

Reputation:

It looks like your problem is that your Lambda function is returning an incorrect response. Lambda functions called by API Gateway via Lambda Proxy Integrations need to return a JSON object in the following format:

{
    "isBase64Encoded": True|False,
    "statusCode": <status code>,
    "headers": {
        "header-name": "header-value",
        # ...
    },
    "body": "{\"your\":\"data\"}" # <--- MUST be a string, NOT an object
}

Your create_new_user function returns format_return(200, request_body), where request_body is the result of get_event_body, which returns json.loads (which returns a dict, not a string).

Changing get_event_body like so should do the trick:

def get_event_body(event):
    print(json.dumps(event))
    return json.dumps(event["body"])

Upvotes: 1

Related Questions