DEV Community

karthikpower
karthikpower

Posted on

How to run lambda integration mode in serverless locally

I want to run serverless application locally earlier this was working using lambda proxy but I want to change it to lambda integration. So I have defined request and response template as follows but when I invoke lambda locally, I see this response,

    {
    "isBase64Encoded": false,
    "statusCode": 200,
    "headers": {
        "access-control-allow-origin": "*",
        "content-type": "application/json; charset=utf-8",
        "content-length": "2",
        "etag": "W/\"2-l9Fw4VUO7kr8CvBlt4zaMCqXZ0w\""
    },
    "body": "[]"
}
Enter fullscreen mode Exit fullscreen mode

but I expect only body in response this breaks running UI locally but when I run the application in aws I get correct response. Is there any additional configuration to be done in serverless.yml. This is how serverless.yml looks like

service: my-service-api

provider:
  name: aws
  runtime: nodejs16.x
  memorySize: 256 
  timeout: 10 
  region: us-west-2
  profile: xyz
  versionFunctions: false
  endpointType: regional
  deploymentBucket:
    name: ps-serverless
  vpc: xyz
  apiGateway:
    restApiId: xyz
    restApiRootResourceId: xyz
    restApiResources:
      /district-settings: xyz
plugins:
  - serverless-offline

custom:
  corsOptions:
    origin: http://localhost:3000/
    headers:
      - Content-Type
      - X-Amz-Date
      - Authorization
      - X-Api-Key
      - X-Amz-Security-Token
      - X-Amz-User-Agent
      - X-Xsrf-Token
    allowCredentials: true
  requestTemplate:
    application/json: |
      #set($request_header = $input.params().header)
      #set($request_query = $input.params().querystring) 
      #set($request_path = $input.params().path)
      #set($request_stage_vars = $stageVariables)
      #set($request_context = $context) 
      {  
        "body": "$util.escapeJavaScript($input.json('$'))",
        "httpMethod": "$context.httpMethod",
        "headers": {
        #foreach($header in $request_header.keySet())
              "$header" : "$util.escapeJavaScript($request_header.get($header))"
              #if($foreach.hasNext),#end
              #end
            }, 

        "queryStringParameters": {
        #foreach($query in $request_query.keySet())
              "$query" : "$util.urlDecode($request_query.get($query))"
              #if($foreach.hasNext),#end
              #end
            }, 

        "pathParameters": {
        #foreach($path in $request_path.keySet())
              "$path" : "$util.escapeJavaScript($request_path.get($path))"
              #if($foreach.hasNext),#end
              #end
            }, 

        "stageVariables": {
        #foreach($stage in $request_stage_vars.keySet())
              "$stage" : "$util.escapeJavaScript($request_stage_vars.get($stage))"
              #if($foreach.hasNext),#end
              #end
            }, 
        "resource": "$context.resourcePath",
        "path":"$context.path",
        "requestContext": {
        #foreach($reqContext in $request_context.keySet())
              "$reqContext" : "$util.escapeJavaScript($request_context.get($reqContext))"
              #if($foreach.hasNext),#end
              #end
            },
        "isBase64Encoded": false
      }

  responseHeaders:
    headers:
      Content-Type: ${env:CONTENT_TYPE}
      Access-Control-Allow-Credentials: ${env:ALLOW_CREDENTIAL}
      Strict-Transport-Security: ${env:SECURE_TRANSPORT_SECURITY}
      Cache-Control: ${env:CACHE_CONTROL}
      Content-Security-Policy: ${env:DEFAULT_CSP}
      X-Content-Type-Options: ${env:CONTENT_TYPE_OPTIONS}
      X-XSS-Protection: ${env:XSS_PROTECTION}
      X-Frame-Options: ${env:X_FRAME_OPTIONS}
      Pragma: ${env:PRAGMA}

    statusCodes:
      200:
        pattern: ''
        template:
          application/json: |
            #set($body = $input.json('$.body'))
            #set($statusCode = $input.json('$.statusCode'))
            #set($Integer = 0)
            $util.parseJson($body)
            #set($origin = $input.params().header)
            #set($context.responseOverride.header.Access-Control-Allow-Origin = $origin)
            #if($body.contains("error"))
            #set($context.responseOverride.status = $Integer.parseInt($statusCode))
            #end

functions:
 # Get list of districts
  listDistricts:
    handler: src/districts/district-handler.list
    events:
      - http:
          path: 'helloWorld'
          method: get
          cors: ${self:custom.corsOptions}
          integration: lambda
          request:
            passThrough: NEVER
            template: ${self:custom.requestTemplate}
          response: ${self:custom.responseHeaders}
Enter fullscreen mode Exit fullscreen mode

Any additional configuration I need to configure to get correct only body in response running locally will be of great help. Also I have GET request with query params that is not passed.

Please note I am using serverless-offline@8.8.1, node version 16. I am running app locally using sls offline start.

Top comments (1)

Collapse
 
dasheck0 profile image
Stefan Neidig

Awesome. Thanks for sharing. Was looking for such a thing for a long time.