npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

serverless-openapi-req-validation

v2.3.0

Published

Automatically generate an opeanpi file from your Serverless Framework config file to be used for validation inside your api gateway

Downloads

281

Readme

Serverless Openapi Req Validation

This plugin allows you to automatically generate an openapi specifications, describing your application endpoints. Additionally, it injects the necessary types and objects into the existing serverless configuration.

Install

yarn add --dev serverless-openapi-req-validation
# or
npm install -D serverless-openapi-req-validation

Add the following plugin to your serverless.yml or serverless.ts:

plugins:
  - serverless-openapi-req-validation
plugins: ['serverless-openapi-req-validation'];

Usage

This plugin is designed to work with vanilla Serverless Framework. The plugin is split into two part:

  • Openapi v3 generation
  • Request validation with API GateWay

The openapi file can be generated by running sls generate-openapi. The request validation can be toggled by uploadTypes (default false).

Request Validation

If enabled the respective requestBody types are transformed AWS::ApiGateway::Model Cloudformation resources and injected in the same stack, so be in mind with the maximum resources per stack. Currently the request validation within API Gateway works with swagger v2.0. Due to the inherit difference between openapi 3 and 2, anyOf constructs are not supported and skipped in the uploading phase. Meaning Union types are not yet supported and skipped in the uploading phase.

Config Options

All config options are optional. Defaults are shown in the table below.

custom:
    autoOpenapi:
        info:
            title: 'string'
            description: 'string'
        apiType: 'http' | 'httpApi'
        typeFiles: ['./src/types/typefile1.d.ts', './src/**/types.ts']
        apiKeyHeaders: ['Authorization', 'anyOtherName']
        outputDir: 'generated'
        uploadTypes: true | false
        compactOutput: true | false
        useStage: true | false
        basePath: '/string'
        host: 'http://some-host'
        excludeStages: ['production', 'anyOtherStage']
        externalDocs:
            url: http://some-doc
            description: some-description
        servers:
            - url: http://some-server
              description: some-description
        openapiTags:
            - some-tag

| Option | Description | Default | Example | |-----------------|-----------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|----------------------------------------------------------------------| | info | Info object according to openapi specifications | { title: Serverless service name, version: Current time | See info-object | | apiType | API type for which your openapi file should be created for. Options are http and httpApi | httpApi | | | uploadTypes | Boolean indicating to upload types to API Gateway on deployment via designated serverless event fields | false | | | compactOutput | During node construction, use anchors and aliases to keep strictly equal non-null objects as equivalent in YAML | false | description: *a2 | | typeFiles | Array of strings which defines where to find the typescript types to use for the request and response bodies | ['./src/types/api-types.d.ts'] | | | apiKeyHeaders | Array of strings used to define API keys used in auth headers | [] | apiKeyHeaders: ['Authorization', 'x-api-key'] | | useStage | Boolean to either use current stage in beginning of path or not | false | true => dev/openapi for stage dev | | basePath | String that can be prepended to every request. Should include leading/ | - |/some-base=>http://localhost/some-base/my-endpoint | |host | String that overrides the host. With this you can set your custom domain for your application endpoints | - |http://some-host=>{http://some-host}/my-endpoint | |excludeStages| Array of strings that contains stages in which openapi should **not** be created and injected in. |[] | | |externalDocs | Object containing theurland optionaldescriptionof where external documentation is located | - |externalDocs: { url: 'some-url', description: 'some-description' }| |servers | Array of server objects |[] |servers: [ { url: 'some-url', description: 'some-description' } ]` |

Adding more details

The default openapi file from vanilla Serverless framework will have the correct paths and methods but no details about the requests or responses.

API Summary and Details

The optional attributes summary and description can be used to describe each HTTP request in Openapi.

openapiTags is an optional array that can be used to group HTTP requests with a collapsible name (i.e. grouping two endpoints GET /dogs and POST /dogs together). If not specified, all HTTP requests will be grouped under default.

http:
    summary: 'This is a cool API'
    description: 'Cool API description is here'
    openapiTags: ['Dogs']

Adding Data Types

This plugin uses typescript types to generate the data types for the endpoints. By default, it pulls the types from src/types/api-types.d.ts.

You can then assign these typescript definitions to requests as requestBody on the http or https config, or to the response as seen just below.

Responses

You can also add expected responses to each of the http endpoint events. This is an object that contains the response code with some example details:

responses:
    # response with description and response body
    200:
        description: 'this went well'
        bodyType: 'helloPostResponse'
    # response with just a description
    400:
        description: 'failed Post'
    # shorthand for just a description
    502: 'server error'
}

Post request expected body

When you create a POST or PUT endpoint, you expect to receive a specific structure of data as the body of the request.

You can do that by adding a requestBody to the http event:

http:
    path: 'hello'
    method: 'post'
    requestBody: 'helloPostBody'

or with an additional description:

http:
    path: 'hello'
    method: 'post'
    requestBody: 
        bodyType: 'helloPostBody'
        description: 'Some Description'

Query String Parameters

If you want to specify the query string parameters on an endpoint you can do this by adding an object of queryStringParameters to the event. This has two required properties of required and type as well as an optional description.

http:
    path: 'goodbye'
    method: 'get'
    queryStringParameters:
        bob:
            required: true
            type: 'string'
            description: 'bob'
        count:
            required: false
            type: 'integer'

If no queryStringParameters are defined, the plugin will do its best to generate params based on any Serverless request.parameters.querystrings that are defined.

Alternatively, one can rely on the default implementation of Serverless request.parameters.querystrings. For both scenarios the plugin will manage the injection of the final template for request validation.

Header Params

Works the same way as queryStringParameters, but for headers.

To use it, just define it under headerParameters:

http:
    path: 'goodbye'
    method: 'get'
    headerParameters:
        bob:
            required: true
            type: 'string'
            description: 'bob'
        count:
            required: false
            type: 'integer'

If no headerParameters are defined, the plugin will do its best to generate headers based on any Serverless request.parameters.headers that are defined.

Alternatively, one can rely on the default implementation of Serverless request.parameters.headers. For both scenarios the plugin will manage the injection of the final template for request validation.

Path Parameters

Path parameters are resolved first by looking at request.parameters.paths, and then by resolving any additional parameters in the http event path (i.e. /{id}). By default, the path will be determined during runtime from your Serverless config if omitted in request.parameters.paths. Thus it is for no need to specify this parameter.

Exclude an endpoint

You can exclude some endpoints from the openapi generation by adding exclude to the http event:

http:
    path: 'hello'
    method: 'post'
    exclude: true

Exclude from validation

Alternatively, you can solely exclude some endpoints to be uploaded to API Gateway for validation by adding disableValidation to the http event:

http:
    path: 'hello'
    method: 'post'
    disableValidation: true

Custom operationId

You can override the automatically generated operationId by adding the operationId property to the http event. This can be useful when using code generators.

http:
    path: 'hello'
    method: 'post'
    operationId: 'postHello'

Annotations

The schema generator uses JSDoc for typescript, which is able to convert annotations to JSON schema properties. See their jsdoc for more examples

For example

export interface Shape {
    /**
     * The size of the shape.
     *
     * @pattern ^[a-zA-Z]+$
     */
    size: string;
}

will be translated to

{
    "Shape": {
        "properties": {
            "size": {
                "description": "The size of the shape.",
                "pattern": "^[a-zA-Z]+$",
                "type": "string"
            }
        },
        "type": "object"
    }
}

Automated Descriptions

Serverless

Descriptions in your openapi specifications can be added as follows:

http:
    path: 'path'
    method: post
    description: "Custom path description"
    summary: "Custom path summary"
    queryStringParameters:
        parameter:
            type: 'string'
            description: 'Custom parameter description'
    requestBody: 
        bodyType: SomeBody
        description: 'Custom requestbody description'
    responses:
        202:
            description: "Custom response description"

The above will result in:

{
  "paths": {
    "/path": {
      "post": {
        "summary": "Custom path summary",
        "parameters": [
          {
            "in": "query",
            "name": "parameter",
            "description": "Custom parameter description",
          }
        ],
        "requestBody": {
          "description": "Custom requestbody description",
        },
        "responses": {
          "202": {
            "description": "Custom response description"
          }
        },
        "description": "Custom path description"
      }
    }
  }
}

Typescript

Multiline comment statements are automatically used in the respective component's schema description. The following example:

/**
 * This is a custom shape
 */
export interface Shape {
    /**
     * The size of the shape.
     */
    size: number;
    type: string;
}

, will result in the following openapi schema:

{
    "Shape": {
        "description": "This is a custom shape",
        "title": "Shape",
        "properties": {
            "size": {
                "description": "The size of the shape.",
                "type": "number"
            }
        },
        "type": "object"
    }
}