# serverless-openapi-req-validation

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

Latest version **2.3.0** (published 2023-05-14) · 0 weekly downloads

## Install

```sh
npm install serverless-openapi-req-validation
pnpm add serverless-openapi-req-validation
yarn add serverless-openapi-req-validation
bun add serverless-openapi-req-validation
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.3.0 |
| Published | 2023-05-14 |
| First published | 2022-11-22 |
| Weekly downloads | 0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 4 |
| Unpacked size | 76.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | daan.rotman |

## Links

- npm: https://www.npmjs.com/package/serverless-openapi-req-validation
- Repository: https://github.com/daanootje/serverless-openapi-req-validation
- Issues: https://github.com/daanootje/serverless-openapi-req-validation/issues
- npm.io page: https://npm.io/package/serverless-openapi-req-validation

## Dependencies (4)

- [yaml](https://npm.io/package/yaml.md) ^2.2.1
- [get-tsconfig](https://npm.io/package/get-tsconfig.md) ^4.3.0
- [@serverless/typescript](https://npm.io/package/@serverless/typescript.md) ^3.25.0
- [ts-json-schema-generator](https://npm.io/package/ts-json-schema-generator.md) ^1.2.0

## Recent versions

- 2.3.0 (latest) — 2023-05-14
- 2.2.0 — 2023-02-18
- 2.1.0 — 2023-01-28
- 2.0.2 — 2023-01-18
- 2.0.1 — 2023-01-18
- 2.0.0 — 2023-01-06
- 1.2.0 — 2023-01-04
- 1.1.4 — 2023-01-04
- 1.1.3 — 2023-01-04
- 1.1.2 — 2023-01-04
- 1.1.1 — 2023-01-04
- 1.1.0 — 2022-11-23
- 1.0.1 — 2022-11-23
- 1.0.0 — 2022-11-22

## 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

```sh
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`:

```yaml
plugins:
  - serverless-openapi-req-validation
```

```ts
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](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-validation-sample-api-swagger.html) 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.

```yaml
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](https://swagger.io/specification/#info-object)                | { title: `Serverless service name`, version: `Current time` | See [info-object](https://swagger.io/specification/#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 the `url` and optional `description` of 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`.

```yaml
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:

```yaml
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:

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

or with an additional description:

```yaml
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`.

```yaml
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`:

```yaml
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:

```yaml
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:

```yaml
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.

```yaml
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](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html) for more examples

For example

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

```json
{
    "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:

```yaml
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:

```json
{
  "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:

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

, will result in the following openapi schema:

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

---
_Source: https://npm.io/package/serverless-openapi-req-validation · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
