Get detailed error messages from AWS API Gateway Request Validator

家住魔仙堡 提交于 2019-11-27 12:32:22

问题


Background

I have an API Gateway created using Swagger 2.0 definitions with API Gateway extensions.

I overrode the default API Gateway responses, for instance:

x-amazon-apigateway-gateway-responses:
  BAD_REQUEST_BODY:
    statusCode: 400
    responseTemplates:
      application/json: |
        {
          "error": {
            "code": 400,
            "stage": "$context.stage",
            "request": "$context.requestId",
            "message": "$context.error.message"
          }
        }

The $context in the above payload comes from API Gateway variables.

A sample resource/method in my API looks like this (always LAMBDA_PROXY integrations):

paths:
  /test:
    post:
      parameters:
        - in: body
          name: Test
          required: true
          schema:
          $ref: "#/definitions/Test"
      responses:
        201:
          description: Created
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
      x-amazon-apigateway-integration:
      uri: >-
        arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${lambda}/invocations
      type: aws_proxy
      httpMethod: POST
      credentials: "${credentials}"
      passthroughBehavior: never

With the corresponding request payload definition:

definitions:
  Test:
    type: object
    title: Test
    required:
      - date
    properties:
      date:
        type: string
        pattern: "^20[0-9]{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$"
        description: Date in YYYY-MM-DD Format

And the request validator extensions:

x-amazon-apigateway-request-validator: body
x-amazon-apigateway-request-validators:
  body:
    validateRequestBody: true
    validateRequestParameters: false

Problem

When I call this endpoint with a missing or invalid date, I always get the same response:

{
    "error": {
        "code": 400,
        "stage": "latest",
        "request": "6b7a64f5-e7f0-11e7-845b-f53ceb4cb049",
        "message": "Invalid request body"
    }
}

However, when I test it through the API Gateway console without the date property:

Request body does not match model schema for content type application/json: [
  object has missing required properties (["date"])
]

And with an invalid date:

Request body does not match model schema for content type application/json: [
  ECMA 262 regex "^20[0-9]{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$" does not match input string "2017/12/25"
]

Question

How can I access the detailed error message so that I can enrich my error response with a more descriptive message than Invalid request body? I suspect that this must be possible, perhaps using x-amazon-apigateway-gateway-responses mapping, but so far I haven't been able to do it.


回答1:


UPDATE:

This is now possible with gateway responses. Setup a gateway response BAD_REQUEST_BODY [docs] with the below template (https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html)

{"message":$context.error.validationErrorString}

(Developer on API Gateway)

Unfortunately, this is not supported right now. We are actively working on fixing this issue, but I can't give you any specific timelines by when this could be supported.




回答2:


Since API Gateway developer had answered the question, I still want to add some tips for you, maybe it is helpful and that can be an accepted answer!

For your question, in fact you need to active the cloudwatch logs for api gateway, with that, you can get more logs than you have before.

Let me know if it included the details for Request Validator

This aws document - How do I enable Amazon CloudWatch Logs for APIs I created in the Amazon API Gateway? gives the steps on how to enable it.

But I prefer to go with this document API Gateway and Lambda Logs, which give the screenshots to follow up easily.

In your api gateway, you should see this is enabled.

Access the API gateway several times, go through the log group which is named as:

API-Gateway-Execution-Logs_{rest-api-id}/{stage_name}

Which has more details than the information you have as Invalid request body and others, such as {"message": "Internal server error"}. It is very useful feature, that save me a lot time troubleshooting serverless and api gateway issues.




回答3:


In this case, within the Gateway Responses section, go to:

Bad Request Body [400]

Change the value of the body mapping template to: 

{"message":$context.error.validationErrorString}

Ex Output:

{
"message": "[instance value (\"us\") not found in enum (possible values: [\"usd\",\"eur\",\"gbp\",\"jpy\",\"aud\",\"chf\",\"cad\",\"nzd\"])]"
}



回答4:


This is not an answer to your question but rather an alternative workaround that we've used in our apps that serves the same purpose (request validation).

Our serverless API started by defining all our endpoints in API Gateway (complete with Swagger documentation). Over time, we've added a lot more endpoints (around 60+ endpoints consisting of legacy REST endpoints, public REST endpoints, and private graphQL endpoints).

Managing this number of endpoints through API Gateway proved to be very tedious, and deploy time took very long (we we're using serverless).

Eventually, we decided to reduce it into three "monolith" serverless applications. Two REST endpoints and one GraphQL endpoint.

So basically, we handled the routing inside our Lambda handlers (and routing is not necessary for GraphQL).

For request validation, it comes for free with GraphQL (another reason to love GraphQL). As for our REST handler, we use JSON schemas and any validation error, we can easily return back to the client together with an HTTP 400 error message.



来源:https://stackoverflow.com/questions/47953570/get-detailed-error-messages-from-aws-api-gateway-request-validator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!