Partilly works with ReDoc as they're still working on OpenAPI 3.1.0 support.
Works well with Stoplight.io
Why OpenAPI 3.1.0 and not 3.0.0?
Because types generated from TypeScript are complex and require at least json-schema draft07 to be described properly.
OpenAPI 3.1.0 is the first version to be fully compatible with JSON Schema - 3.0.0 is just an "extended subset" of draft05
To configure this plugin to generate valid OpenAPI documentation there are two places you'll need to modify in your serverless.yml file, the custom variables section and the http event section for each given function in your service.
For more info on serverless.yml syntax, see their docs.
Models
These will be generated for you from TypeScript.
For information on how to specify these yourself, see Models on the base plugin page.
Functions
To define the documentation for a given function event, you need to create a documentation attribute for your http event in your serverless.yml file.
This plugin will assert the documentation attribute is set on every non private: true function with an http event.
If you wish a function to not be listed on your documentation, you must explicitly set documentation: ~ to disable docs on that function.
The documentation section of the event configuration can contain the following attributes:
summary: a short description of the method
description: a detailed description of the method
tags: an array of tags for this event
deprecated: boolean indicator that indicates clients should migrate away from this function
requestBody: contains description of the request
description: a description of the request body
requestModels: a list of models to describe the request bodies (see requestModels below) - these will be autogenerated for you from TypeScript
queryParams: a list of query parameters (see queryParams below) - these can be autogenerated for you from TypeScript
pathParams: a list of path parameters (see pathParams below) - these can be autogenerated for you from TypeScript
cookieParams: a list of cookie parameters (see cookieParams below)
methodResponses: an array of response models and applicable status codes (see methodResponses) - these will be autogenerated for you from TypeScript
functions:
createUser:
handler: "handler.create"
events:
- http:
path: "create"
method: "post"
documentation:
summary: "Create User"
description: "Creates a user and then sends a generated password email"
requestBody:
description: "A user information object"
requestModels:
application/json: "PutDocumentRequest"
pathParams:
- name: "username"
description: "The username for a user to create"
schema:
type: "string"
pattern: "^[-a-z0-9_]+
quot;
queryParams:
- name: "membershipType"
description: "The user's Membership Type"
schema:
type: "string"
enum:
- "premium"
- "standard"
cookieParams:
- name: "SessionId"
description: "A Session ID variable"
schema:
type: "string"
methodResponses:
- statusCode: 201
responseBody:
description: "A user object along with generated API Keys"
responseModels:
application/json: "PutDocumentResponse"
- statusCode: 500
responseBody:
description: "An error message when creating a new user"
responseModels:
application/json: "ErrorResponse"
queryParams
Query parameters can be described as follow:
name: the name of the query variable
description: a description of the query variable
required: whether the query parameter is mandatory (boolean)
schema: JSON schema (inline or file) or a string representing fully qualified TypeScript type to generate schema from
Note: If schema is not specified one will be autogenerated for you as { "type": "string" } if you specify querystrings in your Serverless request parameters
functions:
foo:
events:
- http:
request:
parameters:
querystrings:
filter: true
# This will be autogenerated for you based on your Serverless config above! No need to write it yourself:
# queryParams:
# - name: "filter"
# required: true
# schema:
# type: "string"
Generated Schema from TypeScript type
export namespace MyApi {
export namespace FooBar {
export namespace Request {
export namespace QueryParams {
// You may use JSdoc to set JSON Schema attributes!
/** @description The filter parameter **/
export type Filter = 'hello' | 'world';
}
}
}
}
functions:
fooBar:
events:
- http:
documentation:
queryParams:
- name: "filter"
schema: "MyApi.FooBar.Request.QueryParams.Filter"
request:
parameters:
querystrings:
filter: false
# This will be autogenerated for you based from TypeScript! No need to write it yourself
# queryParams:
# - name: "filter"
# required: false
# description: "The filter parameter"
# schema:
# type: string
# enum:
# - hello
# - world
pathParams
Path parameters can be described as follow:
name: the name of the query variable
description: a description of the query variable
schema: JSON schema (inline or file) or a string representing fully qualified TypeScript type to generate schema from
functions:
foo:
events:
- http:
request:
parameters:
pahts:
usernameId: true
# This will be autogenerated for you based on your Serverless config above! No need to write it yourself:
# queryParams:
# - name: "filter"
# required: true
# schema:
# type: "string"
Generated Schema from TypeScript type
export namespace MyApi {
export namespace FooBar {
export namespace Request {
export namespace PathParams {
// You may use JSdoc to set JSON Schema attributes!
/** @description The usernameId parameter **/
export type UsernameId = string;
}
}
}
}
functions:
fooBar:
events:
- http:
documentation:
paths:
- name: "usernameId"
schema: "MyApi.FooBar.Request.QueryParams.Filter"
request:
parameters:
paths:
usernameId: true
# This will be autogenerated for you based from TypeScript! No need to write it yourself
# queryParams:
# - name: "filter"
# required: true
# description: "The usernameId parameter"
# schema:
# type: string
cookieParams
TypeScript generation for these isn't supported.
For information on how to specify these yourself, see Cookie Parameters on the base plugin page.
requestModels
The requestModels property allows you to define models for the HTTP Request of the function event.
These will be autogenerated for you from TypeScript by convention.
The plugin will autogenerate a request model for every put, patch or post method based on the TypeScript type found by convention.
The look strategy will be by: ${serverless.custom.documentation.apiNamespace}.${upper-case-name-of-function}.Request.Body
For example, the following function:
functions:
myFunction:
events:
- http:
documentation:
summary: "Does a lot for you"
Will look for the resolve type as its request model:
These will be autogenerated for you from TypeScript by convention.
The plugin will autogenerate a response model for every put, patch, post and get method based on the TypeScript type found by convention.
The response will use the generated type as body, and will have a 200 status code. delete method will be generated with an empty body and 204 status code.
Only application/json response types are supported.
The look strategy will be by: ${serverless.custom.documentation.apiNamespace}.${upper-case-name-of-function}.Response
For example, the following function:
functions:
myFunction:
events:
- http:
documentation:
summary: "Does a lot for you"
Will look for the resolve type as its request model:
The responseHeaders/requestHeaders section of the configuration allows you to define the HTTP headers for the function event.
TypeScript generation for these isn't supported.
For information on how to specify these yourself, see Response Headers on the base plugin page.
customTags
In some cases where a single serverless.yml contains endpoints which can be grouped differently,
you can define custom tags as following:
Next you need to add the plugin to the plugins section of your serverless.yml file.
plugins:
- @conqa/serverless-openapi-documentation
- serverless-openapi-typescript
# NOTE: Order is important here - this plugin must be added after the base @conqa/serverless-openapi-documentation plugin
# This plugin asserts that - you will get a validation message if you get the ordering wrong
Note: Add this plugin afterserverless-offline to prevent issues with String.replaceAll being overridden incorrectly.