Configure sam local start-api to send PUT request payloads only

Viewed 739

My main question is:
How can I configure SAM to create API endpoints without Lambda Proxy Integration?

Details:
I am trying to test an API Gateway + Lambda deployment locally. The Lambda function I have specified is expecting to receive the payload of PUT requests on /some-endpoint as the event when invoked. This is the behavior on AWS when creating this endpoint without Lambda Proxy Integration.

However, it seems that sam local start-api defaults to using Proxy Integration; obviously, this results in an event with unexpected structure for my Lambda. I just tried changing the method to GET, and still see Proxy Integration behavior, so it's not PUT-specific.

I know that the local API Gateway and Lambda are communicating and that my function is otherwise working as I want when I test Lambda with sam local invoke -e sample-payload.json.

I haven't tried sam deploy to know if this is unique to sam local or the general behavior of SAM-specified endpoints.

Clarification: sam local and my Lambda code are functioning, no errors aside from those arising from the unexpected event format due to sam defaulting to Lambda Proxy Integration. The SAM documentation says nothing about configuring the PUT method handling, but maybe someone here can help.

Roughly, my Lambda function (event) is expecting event to be the JSON payload of PUT requests, eg

{"id": "user123"}

If I use the AWS console to set up the API Gateway /some-endpoint resource's PUT method, and do not make this endpoint with Lambda Proxy Integration then API Gateway passes along just the body/payload, as above.

When I use sam local start-api based on the YAML above, then send a PUT to http://localhost:3000/some-endpoint, the request makes it to my Lambda function just fine, but I get the event is now formatted as Proxy Integration. So, event now looks like

{"body": '{"id": "abc123"}', "httpMethod": "GET", ...}

and I have to parse the "body" to get the payload I want.

Ultimately I could change the code to expect Proxy Integration instead, but ideally sam local start-api could send just payloads.


For a minimal example of this:

Lambda Python 3.8 script returning the event for illustration.

my_function.py

import json


def handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps(event)
    }

SAM file, template.yml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MyFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: my_function.handler
      Runtime: python3.8
      CodeUri: .
      Policies: AWSLambdaBasicExecutionRole
      Description: ''
      MemorySize: 128
      Timeout: 3
      Role: 
      Events:
        Api1:
          Type: Api
          Properties:
            Path: /some-endpoint
            Method: PUT

And a payload to PUT.
id-event.json

{"id": "user123"}

What I'm looking for is the response of a PUT to localhost:3000/some-endpoint to be {"id": "user123"}.

0 Answers
Related