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": …
gefragt vor 5 Jahren740 Aufrufe
1 Antwort
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"
beantwortet vor 5 Jahren

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen