Request validation using serverless framework

14,227

Solution 1

To implement request validation using serverless you need to do a couple of things: Include your model/header definitions in your stack, and then tell API gateway to use them for request validation.

You'll need to install the following packages:

And then you'll need to include them in your serverless.yml:

plugins:
  - serverless-reqvalidator-plugin
  - serverless-aws-documentation

Note: below is only a quick run-down of how to incorporate the packages. Visit the packages' documentation pages for more comprehensive examples...

  1. Provide API gateway with a description of your models / headers.

    You can import json schemas for your models, and declare http headers using the serverless-aws-documentation plugin. Here's how you'd add a model to your serverless.yml:

    custom:
      documentation:
        api:
          info:
            version: v0.0.0
            title: Some API title
            description: Some API description
        models:
          - name: SomeLambdaRequest
            contentType: application/json
            schema: ${file(models/SomeLambdaRequest.json)} # reference to your model's json schema file. You can also declare the model inline.
    

    And here's how you'd reference the model in your lambda definition:

    functions:
      someLambda:
        handler: src/someLambda.handler
        events:
          - http:
              # ... snip ...
              documentation:
                summary: some summary
                description: some description
                requestBody:
                  description: some description
                requestModels:
                  application/json: SomeLambdaRequest
    

    You can also declare request headers against your lambda definition like so:

    functions:
      someLambda:
        handler: src/someLambda.handler
        events:
          - http:
              # ... snip ...
              documentation:
                summary: some summary
                description: some description
                requestHeaders:
                  - name: x-some-header
                    description: some header value
                    required: true # true or false
                  - name: x-another-header
                    description: some header value
                    required: false # true or false
    
  2. Tell API gateway to actually use the models for validation

    This part makes use of the serverless-reqvalidator-plugin package, and you need to add AWS::ApiGateway::RequestValidator resources to your serverless.yml file. You can specify whether you want to validate request body, request headers, or both.

    resources:
      Resources:
        onlyBody:
          Type: AWS::ApiGateway::RequestValidator
          Properties:
            Name: 'only-body'
            RestApiId:
              Ref: ApiGatewayRestApi
            ValidateRequestBody: true # true or false
            ValidateRequestParameters: false # true or false
    

    And then on individual functions you can make use of the validator like so:

    functions:
      someLambda:
        handler: src/someLambda.handler
        events:
          - http:
              # ... snip ...
              reqValidatorName: onlyBody # reference and use the 'only-body' request validator
    

Put all together your lambda definition would end up looking a little like this:

functions:
  someLambda:
    handler: src/someLambda.handler
    events:
      - http:
          # ... snip ...
          reqValidatorName: onlyBody # reference and use the 'only-body' request validator
          documentation:
            summary: some summary
            description: some description
            requestBody:
              description: some description
            requestModels:
              application/json: SomeLambdaRequest
            requestHeaders:
              - name: x-some-header
                description: some header value
                required: true # true or false
              - name: x-another-header
                description: some header value
                required: false # true or false

Solution 2

This is now supported by Serverless framework, so there is no need to use external plugins.

To enable requests validation one need is to add the following to the serverless.yml:

  HttpHandler:
    handler: src/lambda/http/create.handler
    events:
      - http:
          method: post
          path: items
          request:
            schemas:
              application/json: ${file(models/create-todo-model.json)}

Instead of keeping the file location directly under application/json you can also keep the name of the model after defining it under serverless.yml file's apiGateway section. link to documentation

Kindly note that, as of Feb-2022, serverless-offline plugin is not validating the http.request.schemas in your local. Though they are supporting deprecated version http.request.schema.

Solution 3

As Ivan indicated, there is no need for external plugins as this is supported by the Serverless framework. However, I think the way to configure this has changed.

functions:
  create:
    handler: posts.create
    events:
      - http:
          path: posts/create
          method: post
          request:
            schema:
              application/json: ${file(create_request.json)}

This example was taken from: https://www.serverless.com/framework/docs/providers/aws/events/apigateway/#request-schema-validators

Solution 4

In case you are like me and you don't want to add plugins as suggested in "https://stackoverflow.com/questions/49133294/request-validation-using-serverless-framework".

If you set parameters as required and want to validate them, you must add a request validator to your serverless.yml

Resources:
  ParameterRequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: ParameterRequestValidator
      RestApiId:
        Ref: ApiGatewayRestApi
      ValidateRequestBody: false
      ValidateRequestParameters: true

  ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate:
    Properties:
      RequestValidatorId:
        Ref: ParameterRequestValidator

The method you want to validate will be named something like ApiGateway<Method><Get | Post | Patch | Put | Delete >:. You can look the name up when you package your serverless functions in the created template files.

Courtesy for this solutions goes to https://github.com/serverless/serverless/issues/5034#issuecomment-581832806

Share:
14,227
Ani Alaverdyan
Author by

Ani Alaverdyan

Updated on June 06, 2022

Comments

  • Ani Alaverdyan
    Ani Alaverdyan almost 2 years

    I am using serverless framework for the backend. How can I implement request validation? (do not want to write validation inside lambda functions).