Search code examples
pythonamazon-web-servicesaws-lambdaaws-api-gateway

Format body mapping templates in API Gateway


Need your help! I have the below Lambda function that will take inputs from the API Gateway (using RestAPI Post method) and pass the same as Payload to a second Lambda function.

    def lambda_handler(event, context):
    
        customerName = event['Name']
        customerEmail = event['EmailAddress']
        
        input = {"Name": customerName, "EmailAddress": customerEmail}
        
        response = lambda_client.invoke(
        FunctionName='arn_of_the_lambda_to_be_invoked',
        InvocationType='Event',
        Payload=json.dumps(input))

Below will be my input to the API Gateway in JSON format -

    {
        "Name": "TestUser",
        "EmailAddress": "test@abc.com"
    }

Have tried Lambda proxy integration and Generic Body Mapping templates (from here). In both occasions, API Gateway returns the below error -

Response Body:

{
  "errorMessage": "'Name'",
  "errorType": "KeyError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 7, in lambda_handler\n    customerName = event['Name']\n"
  ]
}

With the same JSON input when I directly invoke the Lambda from the Lambda console, it works. I know that API Gateway, along with the JSON body, pushes many other things. However, I'm unable to figure out.

How do I get this working?


Solution

  • In the lambda proxy integration, the event will be in the following format.

    {
        "resource": "Resource path",
        "path": "Path parameter",
        "httpMethod": "Incoming request's method name"
        "headers": {String containing incoming request headers}
        "multiValueHeaders": {List of strings containing incoming request headers}
        "queryStringParameters": {query string parameters }
        "multiValueQueryStringParameters": {List of query string parameters}
        "pathParameters":  {path parameters}
        "stageVariables": {Applicable stage variables}
        "requestContext": {Request context, including authorizer-returned key-value pairs}
        "body": "A JSON string of the request payload."
        "isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encode"
    }
    

    the values you posted will be inside body as a json string. you need to parse the json.

    import json
    
    def lambda_handler(event, context):
    
        fullBody = json.loads(event['body'])
        print('fullBody: ', fullBody)
        body = fullBody['body']
        customerName = body['Name']
        customerEmail = body['EmailAddress']
        
        input = {"Name": customerName, "EmailAddress": customerEmail}
        
        response = lambda_client.invoke(
        FunctionName='arn_of_the_lambda_to_be_invoked',
        InvocationType='Event',
        Payload=json.dumps(input))
    

    Input format of a Lambda function for proxy integration

    Please remember that the lambda is expected to return the output in the following format for Lambda Proxy integration.

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