Setting API Gateway Method/Integration Response/Request with Lambda Integration

Im trying to create and API Gateway Lambda Integration (NOT lambda proxy) so I can use some of the more advanced features of API Gateway (namely the Method Request, Integration Request, Integration Response, Method Response features).

I’ve found this guide https://serverless.com/framework/docs/providers/aws/events/apigateway/#lambda-integration for serverless, but looking at this and the masses of AWS documentation around these features, I’m totally lost on how to setup what I need as its not obvious to me how the serverless.yml examples in the link above relate to the instructions/documentation provide by AWS.

Can anyone recommend a good worked example of using Lambda Integration with the advance API Gateway features?

2 Likes

i’m running into the EXACT same issue. I realize this is 18 months old, but did you ever figure this out?

Here is some sample code that I am using to set up lambda integration. This populates the request and response by using velocity templates.

functions:
  getProfile:
    handler: functions/get/getProfile.getProfile
    package:
      include:
        - functions/get/getProfile.js
      exclude:
        - functions/**
    events:
      - http:
          path: profile
          method: get
          authorizer:
            type: COGNITO_USER_POOLS
            authorizerId:
              "Fn::ImportValue": ${self:custom.serviceName}:cognito-authorizer
          cors:
            origin: '*'
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
            allowCredentials: false
            cacheControl: 'max-age=600, s-maxage=600, proxy-revalidate' # Caches on browser and proxy for 10 minutes and doesnt allow proxy to serve out of date content
          integration: lambda
          request:
            passThrough: WHEN_NO_TEMPLATES
            template:
              application/json: ${file(../gateway/templates/genericMappingTemplate.vtl)}
          response:
            statusCodes:
              200:
                pattern:''
              400:
                pattern: '.*"customLambdaError".*'
                template: $input.path('$.errorMessage')

Let me know if this doesn’t cover everything you need or want more info and I will try to help further

1 Like

what do you have your lambda returning? My serverless response looks like this:

response:
  400:
    pattern: '.*"error".*'
    template: $input.path('$.errorMessage')

and my lambda returns:

const response = {
    error: 'some error',
    name: event.name
  };
...
context.done(JSON.stringify(response));

Unfortunately, it is still being returned as a 200 to the client and not a 400:

{
    "errorType": "string",
    "errorMessage": "{\"error\":\"error\",\"name\":\"my-event\"}",
    "trace": []
}

my lambda returns this

catch (error) {
        console.log('original error', error);
        const customError = {
            code: error.code,
            type: 'customLambdaError',
            message: "Unable to get group"
        };
        context.fail(JSON.stringify(customError));
    }

I think setting the context.fail is the key to making it realise it has failed

1 Like

no luck. still getting the same thing. do you have error.code set to 400?

No, error.code is just the type of error returned from aws. “AccessDenied” etc.

It’s not because you are missing the statusCodes in your yml is it? Are the response templates showing up in the Aws console?

1 Like

I’m not sure what you mean by ‘it’s not because you are missing the statusCodes in your yml is it?’ but i did look at the cloudformation-template-update-stack.json and see this so i think you are onto something:

{
              "StatusCode": 400,
              "SelectionPattern": "[\\s\\S]*\\[400\\][\\s\\S]*",
              "ResponseParameters": {
                "method.response.header.Access-Control-Allow-Origin": "'*'"
              },
              "ResponseTemplates": {}
            },

Looks like my response templates are empty. but i have the status codes in my serverless.yml as listed above:

response:
  400:
    pattern: '.*"error".*'
    template: $input.path('$.errorMessage')

If you look at my example above, after response: I have a line saying statusCodes but you don’t?

1 Like

Doh! lol. That was it. Just fixed. Thanks!!!

Awesome. Easily missed!

1 Like