web-dev-qa-db-fra.com

Obtenez des messages d'erreur détaillés du validateur de demandes d'AWS API Gateway

Contexte

J'ai une passerelle API créée à l'aide de définitions Swagger 2.0 avec les extensions API Gateway .

J'ai remplacé les réponses par défaut de la passerelle API, par exemple:

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

Le $context dans la charge ci-dessus provient des variables API Gateway .

Un exemple de ressource/méthode dans mon API ressemble à ceci (toujours les intégrations 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

Avec la définition de charge utile de demande correspondante:

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

Et les extensions de validateur request :

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

Problème

Lorsque j'appelle ce noeud final avec un date manquant ou non valide, j'obtiens toujours la même réponse:

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

Cependant, lorsque je le teste via la console API Gateway sans la propriété date:

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

Et avec un date invalide:

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

Comment puis-je accéder au message d'erreur détaillé afin d'enrichir ma réponse d'erreur avec un message plus descriptif que Invalid request body? Je suppose que cela doit être possible, peut-être en utilisant la correspondance x-Amazon-apigateway-gateway-responses , mais je n’ai pas encore réussi à le faire.

16
Alix Axel

(Développeur sur API Gateway)

Malheureusement, ceci n'est pas supporté pour le moment. Nous travaillons activement à la résolution de ce problème, mais je ne peux pas vous donner de calendrier précis pour lequel cela pourrait être supporté.

11
Abhigna Nagaraja

Ce n'est pas une réponse à votre question, mais plutôt une solution de rechange que nous avons utilisée dans nos applications et qui a le même objectif (validation de la demande).

Notre API sans serveur a commencé par définir tous nos points de terminaison dans API Gateway (avec la documentation Swagger). Au fil du temps, nous avons ajouté beaucoup plus de points de terminaison (environ 60+ points de terminaison composés d'anciens REST hérités, de points de terminaison publics REST et de points de terminaison privés graphQL).

La gestion de ce nombre de points de terminaison via API Gateway s'est avérée très fastidieuse et le temps de déploiement a été très long (nous utilisons serverless).

Finalement, nous avons décidé de le réduire à trois applications "monolithes" sans serveur. Deux points de terminaison REST et un point de terminaison GraphQL.

Donc, fondamentalement, nous avons géré le routage à l'intérieur de nos gestionnaires Lambda (et le routage n'est pas nécessaire pour GraphQL).

Pour la validation de la demande, il est gratuit avec GraphQL (une autre raison d’aimer GraphQL). En ce qui concerne notre gestionnaire REST, nous utilisons des schémas JSON et toute erreur de validation, nous pouvons facilement renvoyer au client avec un message d'erreur HTTP 400.

2
dashmug

Puisqu’un développeur API Gateway a répondu à la question, je souhaite néanmoins ajouter quelques astuces à votre intention. C’est peut-être utile et cela peut être une réponse acceptée!

En ce qui concerne votre question, vous devez en fait activer les journaux de cloudwatch pour la passerelle api, ce qui vous permet d’obtenir plus de journaux qu’auparavant. 

Faites-moi savoir s'il contient les détails pour Request Validator

Ce document aws - Comment activer Amazon CloudWatch Logs pour les API créées dans Amazon API Gateway? donne les étapes sur la façon de l'activer.

Mais je préfère aller avec ce document API Gateway et Lambda Logs , qui permettent de suivre facilement les captures d’écran.

Dans votre passerelle API, vous devriez voir que cela est activé.  enter image description here

Accédez à la passerelle d’API à plusieurs reprises, passez par le groupe de journaux nommé comme suit:

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

 enter image description here

Qui a plus de détails que les informations que vous avez en tant que Invalid request body et d’autres, telles que {"message": "Internal server error"}. C'est une fonctionnalité très utile qui me fait gagner beaucoup de temps à résoudre les problèmes de serveur sans passerelle et de passerelle API.

2
BMW

Dans ce cas, dans la section Gateway Responses, allez à: 

Bad Request Body [400]

Change the value of the body mapping template to: 

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

Sortie Ex: 

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