4

I am setting up an AWS API Gateway using Serverless. Ideally, nothing should be configured using the AWS console, only deploying with Serverless.

I want to have it validate the bodies of requests coming in to the various Lambda functions that are also setup within this project. This validation should be done by comparing the body received to an associated JSON schema file. In the case of incorrectly formatted requests, I want the response to indicate what properties are missing or incorrectly typed.

I found the serverless-reqvalidator-plugin to solve the problem of validating against a schema. The validation item is described in the Resource, the schema is associated with the validation item in the custom section using the serverless-aws-documentation plugin, then finally the function is associated with the validation object in the functions section using the reqValidatorName property in the http event. Ideally, somewhere in here, I'd like to setup what message should be returned in the response in the case of error.

// serverless.yml

resources:
   Resources:
      BodyValidation:  
         Type: "AWS::ApiGateway::RequestValidator"
         Properties:
           Name: 'BodyValidation'
           RestApiId: 
             Ref: ApiGatewayRestApi
           ValidateRequestBody: true
           ValidateRequestParameters: false
           /// Ideally, some property about how to dynamically return an error message for invalid requests would be here, or bellow

custom:
  documentation:
// --- cut out api info
    models:
      - name: BodyValidationRequest
        contentType: "application/json"
        schema: ${file(./SampleValidationRequest.json)}

functions:
   SampleValidationFunction:
      //--- cut handler info
       events: 
         - http: 
              //--- cut path and method info
              reqValidatorName: BodyValidation
              documentation: // --- cut documentation info


I did it this way as directed by this answer for a similar question. I would be interested in doing this without relying on the reqvalidator plugin, but in this example given in the AWS API Gateway documentation,it doesn't show how to do it with Serverless.

It looks like this wasn't possible in the past, but it seems to be possible now. I can't find any examples using strictly the serverless.yml though.

I am testing requests in both the AWS Console and Postman. As an example, here is a schema I am testing against:

// SampleValidationRequest.json

{
  "type": "object",
  "properties" :{
    "name": {
      "type": "string"
    },
    "id": {
      "type": "number"
    }
  },
  "required": ["name", "id"]
}

When a send a body that is missing a parameter, such as id with:

{
    "name": "test"
}

I receive back in the response body

{
  "message": "Invalid request body"
}

I would like it to instead say something like what I see when looking at the logs in AWS

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

So, to summarize:

1. Is it possible to add some property that dynamically explains what is wrong with the request body in the response message?

2. Is it possible to validate a request body against a schema just using the setup from Serverless for the AWS API, instead of using reqvalidator?

rDev
  • 237
  • 2
  • 15

1 Answers1

6
  1. Is it possible to add some property that dynamically explains what is wrong with the request body in the response message?

To an extent. See this thread: https://github.com/serverless/serverless/issues/3896

You will need to add a resource attribute to serverless.yml like so:

resources:
  Resources:
    ApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: ${self:provider.stage}-${self:service}
    GatewayResponseResourceNotFound:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        ResponseType: BAD_REQUEST_BODY
        "StatusCode" : "422"
        ResponseTemplates:
          application/json: "{\"message\": \"$context.error.message\", \"error\": \"$context.error.validationErrorString\"}"
  1. Is it possible to validate a request body against a schema just using the setup from Serverless for the AWS API, instead of using reqvalidator?

Yes, it is possible. Make sure you update to the latest version of Serverless otherwise it will silently fail to generate the API Gateway Model.

Here's a setup that works for me:

    events:
      - http:
          path: my_method/
          method: post
          request:
            schema:
              application/json: ${file(validate_my_method.json)}
Gideon A.
  • 111
  • 2
  • 5