Integration Responses Not Created By Serverless


#1

Hello,

I am deploying an API and a lambda function via serverless. While the deployment is successful, the API does not have any integration responses created. If i manually create the responses and do another serverless deployment, the serverless deployment erases my configuration.

This causes a 500 internal server error as a response even though the lambda is invoked and a correct response is being returned by the lambda. The error that i get is as follows:

Execution failed due to configuration error: No match for output mapping and no default output mapping configured

Any idea what must be causing this?

Regards


#2

Hi Ranjani,

I think I experienced the same issue.

tl;dr: depending on your set up, it might be sufficient to populate the response property in your http event, like so

...
signUrl:
    handler: handler.signUrl
    events:
      - http:
          path: signUrl
          method: get
          integration: lambda
          cors: true
          response:
            body:
              Content-Type: "'application/json'"
          authorizer:
            arn: ${self:custom.poolArn}
...

setup: serverless version 1.26.0 with serverless-plugin-bind-deployment-id.

context: I wanted to enable caching in ApiGateway and override the default behavior for some of the methods. To do so, I had to deploy a custom AWS::ApiGateway::Stage, hence the need of serverless-plugin-bind-deployment-id.

what happened: It looks like when I added the custom stage to my resources all of my endpoints started failing with error 500 and ApiGateway complaining as follows

I checked the CloudFormation templates that were generated before and after I added my custom stage and the difference is that in every AWS::ApiGateway::Method configurations for Properties.Integration.IntegrationResponse and Properties.MethodResponses were empty lists as opposed to the expected list of configurations. In detail, the following is what was missing

IntegrationResponses

IntegrationResponses:
          - StatusCode: 200
            SelectionPattern: ''
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 400
            SelectionPattern: '[\s\S]*\[400\][\s\S]*'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 401
            SelectionPattern: '[\s\S]*\[401\][\s\S]*'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 403
            SelectionPattern: '[\s\S]*\[403\][\s\S]*'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 404
            SelectionPattern: '[\s\S]*\[404\][\s\S]*'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 422
            SelectionPattern: '[\s\S]*\[422\][\s\S]*'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 500
            SelectionPattern: >-
              [\s\S]*(Process\s?exited\s?before\s?completing\s?request|\[500\])[\s\S]*
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 502
            SelectionPattern: '[\s\S]*\[502\][\s\S]*'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}
          - StatusCode: 504
            SelectionPattern: '([\s\S]*\[504\][\s\S]*)|(^[Task timed out].*)'
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: '''*'''
            ResponseTemplates: {}

MethodResponses

MethodResponses:
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 200
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 400
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 401
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 403
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 404
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 422
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 500
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 502
        - ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true
          ResponseModels: {}
          StatusCode: 504

My Custom Resources

 ApiGatewayStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        DeploymentId:
          Ref: __deployment__ # provided by serverless-plugin-bind-deployment-id
        CacheClusterEnabled: true
        CacheClusterSize: "0.5"
        RestApiId:
          Ref: ApiGatewayRestApi
        StageName : ${self:provider.stage}
        MethodSettings:
          - HttpMethod: "*"
            LoggingLevel: INFO
            ResourcePath: "/*"
            CachingEnabled: false
          - HttpMethod: "GET"
            LoggingLevel: INFO
            ResourcePath: "/~1method1"
            CacheTtlInSeconds: 600
            CachingEnabled: true
          - HttpMethod: "GET"
            LoggingLevel: INFO
            ResourcePath: "/~1method2"
            CacheTtlInSeconds: 600
            CachingEnabled: true

Hope this helps,
please keep us updated about your issue :smiley: