API Gateway Lambda integration SelectionPattern doesn't match

0

My Lambda-backed API Gateway endpoint always returns 200 regardless of integration responses.

I have a rather simple GET endpoint:

    public void process(InputStream inputStream, OutputStream outputStream) throws IOException {
        Tenant tenant = tenantsDao.getTenant(inputStream);

        if (tenant != null) {
            this.getObjectMapper().writerWithView(Tenant.TenantData.class).writeValue(outputStream, tenant);
        } else {
            throw new ApiKeyNotFoundException("API key not found.");
        }
    }

This correctly prints the error when I execute it via CURL:

$ curl https://<my_api_url>/keys/foo -v
…
< HTTP/2 200 
…
{"errorMessage":"API key not found.","errorType":"…"}

Even though I have the integration response mapping set:

    ApiMethodGetKeysApiKey:
        Type: "AWS::ApiGateway::Method"
        Properties:
            RestApiId: !Ref "ApiGatewayV1"
            ResourceId: !Ref "ApiResourceKeysApiKey"
            HttpMethod: "GET"
            AuthorizationType: "CUSTOM"
            AuthorizerId: !Ref "ApiAuthorizerV1"
            RequestValidatorId: !Ref "ParametersOnlyValidator"
            RequestParameters:
                method.request.header.Authorization: true
                method.request.path.apiKey: true
            MethodResponses:
                -
                    StatusCode: 200
                -
                    StatusCode: 404
            Integration:
                Type: "AWS"
                IntegrationHttpMethod: "POST"
                Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${!stageVariables.KeyFetchingTarget}"
                Credentials: !GetAtt "ApiGatewayRole.Arn"
                RequestTemplates:
                    application/json: |
                        {
                            "tenantId": "$context.authorizer.tenantId",
                            "apiKey": "$input.params('apiKey')"
                        }
                IntegrationResponses:
                    -
                        StatusCode: 200
                    -
                        StatusCode: 404
                        SelectionPattern: ".*API key not found.*"
                        ResponseTemplates:
                            application/json: |
                                {
                                    "message": "$input.path('$.errorMessage')"
                                }
                PassthroughBehavior: "NEVER"

Am I missing something?

API Gateway execution logs shows that the Lambda error header is set properly:

(2f8d1403-be70-11e9-a7ce-dd90ab730381) Endpoint response headers: {Date=Wed, 14 Aug 2019 08:47:45 GMT, Content-Type=application/json, Content-Length=720, Connection=keep-alive, x-amzn-RequestId=1f731b7f-5f10-4c3d-87b1-b879379d7d5f, X-Amz-Function-Error=Unhandled, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-5d53cab1-6b333258463add60633ec5a8;parent=4013ac81631b59eb;sampled=1}
(2f8d1403-be70-11e9-a7ce-dd90ab730381) Endpoint response body before transformations:
{
    "errorMessage": "API key not found.",
    "errorType": …
asked 5 years ago729 views
1 Answer
0

The issue was resolved with assistance of AWS support team. The issue was, that if we format integration endpoint like that API Gateway doesn't recognize that it's a Lambda and handles response in different way (falls back to generic AWS integration).

Proper format of integration URI should be:

Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${!stageVariables.KeyFetchingTarget}/invocations"
answered 5 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions