Получать подробные сообщения об ошибках с помощью проверки валидатора шлюза AWS API

Фон

У меня есть API-шлюз, созданный с использованием определений Swagger 2.0 с расширениями API-шлюза.

Я перепробовал ответы API-шлюза по умолчанию, например:

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"
          }
        }

В приведенной выше полезной нагрузке $context поступает переменные API-шлюза.

Образец ресурса/метода в моем API выглядит так (всегда LAMBDA_PROXY):

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

С соответствующим определением полезной нагрузки запроса:

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

И запросить расширения валидатора:

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

Проблема

Когда я вызываю эту конечную точку с отсутствующим или недопустимым date, я всегда получаю тот же ответ:

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

Однако, когда я тестирую его через консоль API Gateway без свойства date:

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

И с недопустимым 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"
]

Вопрос

Как я могу получить доступ к подробному сообщению об ошибке, чтобы я мог обогатить свой ответ об ошибке более подробным сообщением, чем Invalid request body? Я подозреваю, что это должно быть возможно, возможно, используя x-amazon-apigateway-gateway-responses, но до сих пор я не смог это сделать.

Ответ 1

UPDATE:

Это теперь возможно с ответами шлюза. Настройте ответ шлюза BAD_REQUEST_BODY [docs] с помощью приведенного ниже шаблона (https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html)

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

(разработчик на API Gateway)

К сожалению, сейчас это не поддерживается. Мы активно работаем над исправлением этой проблемы, но я не могу дать вам конкретные сроки, когда это может быть поддержано.

Ответ 2

Поскольку разработчик API Gateway ответил на этот вопрос, я все же хочу добавить несколько советов для вас, может быть, это полезно, и это может быть приемлемым ответом!

На ваш вопрос, на самом деле вам нужно активировать журналы cloudwatch для API-шлюза, при этом вы можете получить больше журналов, чем раньше.

Дайте мне знать, если он содержит детали для Request Validator

Этот документ aws. Как включить журналы Amazon CloudWatch для API, которые я создал в Amazon API Gateway? содержит инструкции по его включению.

Но я предпочитаю использовать этот документ API Gateway и Lambda Logs, в которых скриншоты легко отслеживать.

В вашем API-шлюзе вы должны увидеть, что это включено. enter image description here

Получите доступ к шлюзу API несколько раз, просмотрите группу журналов, которая называется:

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

enter image description here

Который имеет больше деталей, чем информация, которую вы имеете как Invalid request body и другие, такие как {"message": "Internal server error"}. Это очень полезная функция, которая позволяет мне сэкономить много времени на устранении неполадок, связанных с сервером и API-шлюзом.

Ответ 3

В этом случае в разделе Ответы шлюза перейдите по адресу:

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

Это не ответ на ваш вопрос, а скорее альтернативное обходное решение, которое мы использовали в наших приложениях, которые выполняют одну и ту же цель (проверка запроса).

Наш серверный API запущен путем определения всех наших конечных точек в API Gateway (в комплекте с документацией Swagger). Со временем мы добавили намного больше конечных точек (около 60+ конечных точек, состоящих из устаревших конечных точек REST, открытых конечных точек REST и частных конечных точек графика).

Управление этим количеством конечных точек через API Gateway оказалось очень утомительным, и время развертывания заняло очень много времени (мы используем serverless).

В конце концов, мы решили сократить его на три "монолитных" безсерверных приложения. Две конечные точки REST и одна конечная точка GraphQL.

Итак, в основном мы обрабатывали маршрутизацию внутри наших обработчиков Lambda (а для GraphQL не требуется маршрутизация).

Для проверки запроса он поставляется бесплатно с GraphQL (еще одна причина любить GraphQL). Что касается нашего обработчика REST, мы используем схемы JSON и любую ошибку проверки, мы можем легко вернуться к клиенту вместе с сообщением об ошибке HTTP 400.