How to test AWS APIGateway – Lambda trigger in local

Difference in local and the actual environment

Let’s assume that you have an AWS API Gateway proxy setup backed by lambda and lambda will handle all the requests. I had the same setup and like to test it in local using rest clients like Postman or Insomnia before deploying in the lambda.

Prerequisites:

In this tutorial, I have used AWS SAM CLI to test this trigger.

  1. AWS SAM CLI (Installation link) is the only prerequisite

Lambda(API) Code:

For this tutorial, I have created a lambda based on Python. But the configuration will be similar for nodejs or java as well.

def lambda_handler(event, context):
  httpMethod = event.get("httpMethod")
  url = event.get("path")
  body = event.get("body")
  params = event.get("queryStringParameters")
  print(httpMethod, url, params)
  if httpMethod == 'GET' and url == '/get':
    return {
        'statusCode': 200,
        'body': '{"status":"success"}',
        'headers' : {
          'Access-Control-Allow-Origin' : '*',
          'Access-Control-Allow-Methods' : 'GET, POST, OPTIONS, PUT, PATCH, DELETE'
        }
    }
  else:  
    return {
        'statusCode': 422,
        'body': json.dumps('Not supported')
    }

The end user will request using the AWS APIGateway URL and the lambda proxy is configured to handle all the requests. Once the URL is hit, the request information will come to lambda as an event object.

In the first few lines, we are just extracting the request information like HTTPMethod, request body, query params and path from the event object. Then we just return the status as a success if the endpoint matches otherwise just returned the 422 status code.

SAM Configuration:

The above code will work if we configure it directly in the lambda and APIGateway. But the problem arises when we like to test the business logic of the lambda code.

“template.yml” is the default configuration file name used by the SAM CLI. The next step is that we need to tell the SAM that the given lambda acts as the handler for the APIGateway trigger.

Transform: AWS::Serverless-2016-10-31

Parameters:

  SOME_RANDOM_VARIABLE:
    Type: String
    Default: Hello, I'm env variable

Globals:
  Api:
    Cors:
      AllowMethods: "'GET, POST, OPTIONS, PUT, PATCH, DELETE'"
      AllowHeaders: "'content-type'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"

Resources:
  matcher:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.lambda_handler
      Runtime: python3.6
      Environment:
        Variables:
          SOME_RANDOM_VARIABLE: 
      Events:
        Api:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: any

We can define all possible resources under the “Resources” section. For this demo, we named this lambda service “matcher” and related properties under “Resources.matcher“.

Notable configurations are explained below.

  1. Handler – Link to lambda handler and the format is <file_name>.<function_name>
  2. Environment – If there are any environment variables, those can be passed here
  3. Events – Type of the event we are gonna receive in the handler. In this case, it’s API
  4. Events.Properties.Path – If we are going to configure the handler for only one endpoint, then we can specify the resource path here. In this case, I have configured as /{proxy+} to handle all the requests.

Run:

At last, we need to run this using the following command.

sam local start-api --env-vars env.json -p 3080

start-api – is the command to start this code as a server in local development environment.

–env-vars – is an optional field and can be passed if there are any environment variables.

-p 3080 – is the port name in which you can test your API.

Once we run this command, we can test our API using the http://localhost:3080 endpoint.

You can find this code here. <github_link>

Published