serverless-openapi-documenter 0.0.67 → 0.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -192
- package/package.json +1 -1
- package/src/definitionGenerator.js +3 -2
package/README.md
CHANGED
|
@@ -12,9 +12,7 @@
|
|
|
12
12
|
</a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
This will generate an OpenAPI V3 (up to v3.0.3) file for you from your serverless file. It can optionally generate a [Postman Collection V2](https://github.com/postmanlabs/openapi-to-postman) from the OpenAPI file for you too. This currently works for `http` and `httpApi` configurations.
|
|
15
|
+
This will generate an OpenAPI V3 (up to v3.0.3) file for you from your serverless file. It can optionally generate a [Postman Collection V2](https://github.com/postmanlabs/openapi-to-postman) from the OpenAPI file for you too. This currently works for `http` and `httpApi` configurations.
|
|
18
16
|
|
|
19
17
|
Originally based off of: https://github.com/temando/serverless-openapi-documentation
|
|
20
18
|
|
|
@@ -25,6 +23,7 @@ This plugin works for Serverless 2.x and up and only supports node.js 14 and up.
|
|
|
25
23
|
To add this plugin to your package.json:
|
|
26
24
|
|
|
27
25
|
**Using npm:**
|
|
26
|
+
|
|
28
27
|
```bash
|
|
29
28
|
npm install --save-dev serverless-openapi-documenter
|
|
30
29
|
```
|
|
@@ -55,79 +54,83 @@ Options:
|
|
|
55
54
|
### README Highlighted Reading
|
|
56
55
|
|
|
57
56
|
#### Security Details
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
|
|
58
|
+
- [Security](#securityschemes)
|
|
59
|
+
- [Security on All Operations](#security-on-each-operation)
|
|
60
|
+
- [Security Per Operation](#security)
|
|
61
|
+
|
|
61
62
|
#### Model Details
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
|
|
64
|
+
- [Models](#models)
|
|
65
|
+
- [Notes on Schemas](#notes-on-schemas)
|
|
66
|
+
- [Request Schema Validators](#serverless-request-schema-validators)
|
|
67
|
+
|
|
65
68
|
#### Response Headers
|
|
66
|
-
* [CORS](#cors)
|
|
67
|
-
* [OWASP Secure Headers](#owasp)
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
- [CORS](#cors)
|
|
71
|
+
- [OWASP Secure Headers](#owasp)
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|--------------------------|------------------------------------------------------------------------------------|
|
|
73
|
-
| info.title | custom.documentation.title OR service |
|
|
74
|
-
| info.description | custom.documentation.description OR blank string |
|
|
75
|
-
| info.version | custom.documentation.version OR random v4 uuid if not provided |
|
|
76
|
-
| info.termsOfService | custom.documentation.termsOfService |
|
|
77
|
-
| info.contact | custom.documentation.contact |
|
|
78
|
-
| info.contact.name | custom.documentation.contact.name OR blank string |
|
|
79
|
-
| info.contact.url | custom.documentation.contact.url if provided |
|
|
80
|
-
| info.license | custom.documentation.license |
|
|
81
|
-
| info.license.name | custom.documentation.license.name OR blank string |
|
|
82
|
-
| info.license.url | custom.documentation.license.url if provided |
|
|
83
|
-
| externalDocs.description | custom.documentation.externalDocumentation.description |
|
|
84
|
-
| externalDocs.url | custom.documentation.externalDocumentation.url |
|
|
85
|
-
| security | custom.documentation.security |
|
|
86
|
-
| servers[].description | custom.documentation.servers.description |
|
|
87
|
-
| servers[].url | custom.documentation.servers.url |
|
|
88
|
-
| servers[].variables | custom.documentation.servers.variables |
|
|
89
|
-
| tags[].name | custom.documentation.tags.name |
|
|
90
|
-
| tags[].description | custom.documentation.tags.description |
|
|
91
|
-
| tags[].externalDocs.url | custom.documentation.tags.externalDocumentation.url |
|
|
92
|
-
| tags[].externalDocs.description | custom.documentation.tags.externalDocumentation.description |
|
|
93
|
-
| path[path] | functions.functions.events.[http OR httpApi].path |
|
|
94
|
-
| path[path].summary | functions.functions.summary |
|
|
95
|
-
| path[path].description | functions.functions.description |
|
|
96
|
-
| path[path].servers[].description | functions.functions.servers.description |
|
|
97
|
-
| path[path].servers[].url | functions.functions.servers.url |
|
|
98
|
-
| path[path].[operation] | functions.functions.[http OR httpApi].method |
|
|
99
|
-
| path[path].[operation].summary | functions.functions.[http OR httpApi].documentation.summary |
|
|
100
|
-
| path[path].[operation].description | functions.functions.[http OR httpApi].documentation.description |
|
|
101
|
-
| path[path].[operation].operationId | functions.functions.[http OR httpApi].documentation.operationId OR functionName |
|
|
102
|
-
| path[path].[operation].deprecated | functions.functions.[http OR httpApi].documentation.deprecated |
|
|
103
|
-
| path[path].[operation].externalDocs.description | functions.functions.[http OR httpApi].documentation.externalDocumentation.description |
|
|
104
|
-
| path[path].[operation].externalDocs.url | functions.functions.[http OR httpApi].documentation.externalDocumentation.url |
|
|
105
|
-
| path[path].[operation].servers[].description | functions.functions.[http OR httpApi].documentation.servers.description |
|
|
106
|
-
| path[path].[operation].servers[].url | functions.functions.[http OR httpApi].documentation.servers.url |
|
|
107
|
-
| path[path].[operation].security | functions.functions.[http OR httpApi].documentation.security |
|
|
108
|
-
| path[path].[operation].deprecated | functions.functions.[http OR httpApi].documentation.deprecated |
|
|
109
|
-
| path[path].[operation].parameters | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params |
|
|
110
|
-
| path[path].[operation].parameters.name | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.name |
|
|
111
|
-
| path[path].[operation].parameters.in | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params |
|
|
112
|
-
| path[path].[operation].parameters.description | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.description |
|
|
113
|
-
| path[path].[operation].parameters.required | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.required |
|
|
114
|
-
| path[path].[operation].parameters.deprecated | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.deprecated |
|
|
115
|
-
| path[path].[operation].parameters.allowEmptyValue | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.allowEmptyValue |
|
|
116
|
-
| path[path].[operation].parameters.style | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.style |
|
|
117
|
-
| path[path].[operation].parameters.explode | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.explode |
|
|
118
|
-
| path[path].[operation].parameters.allowReserved | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.allowReserved |
|
|
119
|
-
| path[path].[operation].parameters.schema | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.schema |
|
|
120
|
-
| path[path].[operation].parameters.example | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.example |
|
|
121
|
-
| path[path].[operation].parameters.examples | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.examples |
|
|
122
|
-
| path[path].[operation].requestBody | functions.functions.[http OR httpApi].documentation.requestBody |
|
|
123
|
-
| path[path].[operation].requestBody.description | functions.functions.[http OR httpApi].documentation.requestBody.description |
|
|
124
|
-
| path[path].[operation].requestBody.required | functions.functions.[http OR httpApi].documentation.requestBody.required |
|
|
125
|
-
| path[path].[operation].requestBody.content | functions.functions.[http OR httpApi].documentation.requestModels[contentType].name Links to custom.documentation.models.name |
|
|
126
|
-
| path[path].[operation].responses | functions.functions.[http OR httpApi].documentation.methodResponses |
|
|
127
|
-
| path[path].[operation].requestBody.[statusCode] | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode] |
|
|
128
|
-
| path[path].[operation].requestBody.[statusCode].description | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseBody.description |
|
|
129
|
-
| path[path].[operation].requestBody.[statusCode].content | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseModels[contentType] Links to custom.documentation.models.name |
|
|
73
|
+
### OpenAPI Mapping
|
|
130
74
|
|
|
75
|
+
| OpenAPI field | Serverless field |
|
|
76
|
+
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| info.title | custom.documentation.title OR service |
|
|
78
|
+
| info.description | custom.documentation.description OR blank string |
|
|
79
|
+
| info.version | custom.documentation.version OR random v4 uuid if not provided |
|
|
80
|
+
| info.termsOfService | custom.documentation.termsOfService |
|
|
81
|
+
| info.contact | custom.documentation.contact |
|
|
82
|
+
| info.contact.name | custom.documentation.contact.name OR blank string |
|
|
83
|
+
| info.contact.url | custom.documentation.contact.url if provided |
|
|
84
|
+
| info.license | custom.documentation.license |
|
|
85
|
+
| info.license.name | custom.documentation.license.name OR blank string |
|
|
86
|
+
| info.license.url | custom.documentation.license.url if provided |
|
|
87
|
+
| externalDocs.description | custom.documentation.externalDocumentation.description |
|
|
88
|
+
| externalDocs.url | custom.documentation.externalDocumentation.url |
|
|
89
|
+
| security | custom.documentation.security |
|
|
90
|
+
| servers[].description | custom.documentation.servers.description |
|
|
91
|
+
| servers[].url | custom.documentation.servers.url |
|
|
92
|
+
| servers[].variables | custom.documentation.servers.variables |
|
|
93
|
+
| tags[].name | custom.documentation.tags.name |
|
|
94
|
+
| tags[].description | custom.documentation.tags.description |
|
|
95
|
+
| tags[].externalDocs.url | custom.documentation.tags.externalDocumentation.url |
|
|
96
|
+
| tags[].externalDocs.description | custom.documentation.tags.externalDocumentation.description |
|
|
97
|
+
| path[path] | functions.functions.events.[http OR httpApi].path |
|
|
98
|
+
| path[path].summary | functions.functions.summary |
|
|
99
|
+
| path[path].description | functions.functions.description |
|
|
100
|
+
| path[path].servers[].description | functions.functions.servers.description |
|
|
101
|
+
| path[path].servers[].url | functions.functions.servers.url |
|
|
102
|
+
| path[path].[operation] | functions.functions.[http OR httpApi].method |
|
|
103
|
+
| path[path].[operation].summary | functions.functions.[http OR httpApi].documentation.summary |
|
|
104
|
+
| path[path].[operation].description | functions.functions.[http OR httpApi].documentation.description |
|
|
105
|
+
| path[path].[operation].operationId | functions.functions.[http OR httpApi].documentation.operationId OR functionName |
|
|
106
|
+
| path[path].[operation].deprecated | functions.functions.[http OR httpApi].documentation.deprecated |
|
|
107
|
+
| path[path].[operation].externalDocs.description | functions.functions.[http OR httpApi].documentation.externalDocumentation.description |
|
|
108
|
+
| path[path].[operation].externalDocs.url | functions.functions.[http OR httpApi].documentation.externalDocumentation.url |
|
|
109
|
+
| path[path].[operation].servers[].description | functions.functions.[http OR httpApi].documentation.servers.description |
|
|
110
|
+
| path[path].[operation].servers[].url | functions.functions.[http OR httpApi].documentation.servers.url |
|
|
111
|
+
| path[path].[operation].security | functions.functions.[http OR httpApi].documentation.security |
|
|
112
|
+
| path[path].[operation].deprecated | functions.functions.[http OR httpApi].documentation.deprecated |
|
|
113
|
+
| path[path].[operation].parameters | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params |
|
|
114
|
+
| path[path].[operation].parameters.name | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.name |
|
|
115
|
+
| path[path].[operation].parameters.in | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params |
|
|
116
|
+
| path[path].[operation].parameters.description | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.description |
|
|
117
|
+
| path[path].[operation].parameters.required | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.required |
|
|
118
|
+
| path[path].[operation].parameters.deprecated | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.deprecated |
|
|
119
|
+
| path[path].[operation].parameters.allowEmptyValue | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.allowEmptyValue |
|
|
120
|
+
| path[path].[operation].parameters.style | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.style |
|
|
121
|
+
| path[path].[operation].parameters.explode | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.explode |
|
|
122
|
+
| path[path].[operation].parameters.allowReserved | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.allowReserved |
|
|
123
|
+
| path[path].[operation].parameters.schema | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.schema |
|
|
124
|
+
| path[path].[operation].parameters.example | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.example |
|
|
125
|
+
| path[path].[operation].parameters.examples | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.examples |
|
|
126
|
+
| path[path].[operation].requestBody | functions.functions.[http OR httpApi].documentation.requestBody |
|
|
127
|
+
| path[path].[operation].requestBody.description | functions.functions.[http OR httpApi].documentation.requestBody.description |
|
|
128
|
+
| path[path].[operation].requestBody.required | functions.functions.[http OR httpApi].documentation.requestBody.required |
|
|
129
|
+
| path[path].[operation].requestBody.content | functions.functions.[http OR httpApi].documentation.requestModels[contentType].name Links to custom.documentation.models.name |
|
|
130
|
+
| path[path].[operation].responses | functions.functions.[http OR httpApi].documentation.methodResponses |
|
|
131
|
+
| path[path].[operation].responses.[statusCode] | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode] |
|
|
132
|
+
| path[path].[operation].responses.[statusCode].description | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseBody.description |
|
|
133
|
+
| path[path].[operation].responses.[statusCode].content | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseModels[contentType] Links to custom.documentation.models.name |
|
|
131
134
|
|
|
132
135
|
### Configuration
|
|
133
136
|
|
|
@@ -138,9 +141,9 @@ The `custom` section of your `serverless.yml` can be configured as below:
|
|
|
138
141
|
```yml
|
|
139
142
|
custom:
|
|
140
143
|
documentation:
|
|
141
|
-
version:
|
|
142
|
-
title:
|
|
143
|
-
description:
|
|
144
|
+
version: "1"
|
|
145
|
+
title: "My API"
|
|
146
|
+
description: "This is my API"
|
|
144
147
|
termsOfService: https://google.com
|
|
145
148
|
externalDocumentation:
|
|
146
149
|
url: https://google.com
|
|
@@ -164,7 +167,7 @@ custom:
|
|
|
164
167
|
models: {}
|
|
165
168
|
```
|
|
166
169
|
|
|
167
|
-
Mostly everything here is optional.
|
|
170
|
+
Mostly everything here is optional. A version from a UUID will be generated for you if you don't specify one, title will be the name of your service if you don't specify one. You will need to specify the `documentation` top object.
|
|
168
171
|
|
|
169
172
|
#### termsOfService
|
|
170
173
|
|
|
@@ -272,15 +275,15 @@ This will apply the requirement of each operation requiring your `my_api_key` se
|
|
|
272
275
|
|
|
273
276
|
#### Models
|
|
274
277
|
|
|
275
|
-
There are two ways to write the Models.
|
|
278
|
+
There are two ways to write the Models. Models contain additional information that you can use to define schemas for endpoints. You must define the _content type_ for each schema that you provide in the models.
|
|
276
279
|
|
|
277
280
|
The first way of writing the model is:
|
|
278
|
-
|
|
281
|
+
_required_ directives for the models section are as follow:
|
|
279
282
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
283
|
+
- `name`: the name of the schema
|
|
284
|
+
- `description`: a description of the schema
|
|
285
|
+
- `contentType`: the content type of the described request/response (ie. `application/json` or `application/xml`).
|
|
286
|
+
- `schema`: The JSON Schema ([website](http://json-schema.org/)) that describes the model. You can either use inline `YAML` to define these or use either an external file schema that serverless will resolve (as below), or a reference to an externally hosted schema that will be attempted to be resolved.
|
|
284
287
|
|
|
285
288
|
```yml
|
|
286
289
|
custom:
|
|
@@ -310,7 +313,7 @@ custom:
|
|
|
310
313
|
- name: someObjectInlineExample
|
|
311
314
|
summary: an example of a request
|
|
312
315
|
description: a longer string than the summary
|
|
313
|
-
value: {SomeObject: {SomeAttribute:
|
|
316
|
+
value: { SomeObject: { SomeAttribute: "attribute" } }
|
|
314
317
|
- name: someObjectExternalExample
|
|
315
318
|
summary: an example of a request external
|
|
316
319
|
description: a longer string than the summary
|
|
@@ -319,9 +322,9 @@ custom:
|
|
|
319
322
|
|
|
320
323
|
The Second way of writing the models:
|
|
321
324
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
- `name`: the name of the schema
|
|
326
|
+
- `description`: a description of the schema
|
|
327
|
+
- `content`: an Object made up of the contentType and the schema, as shown below
|
|
325
328
|
|
|
326
329
|
```yml
|
|
327
330
|
custom:
|
|
@@ -354,7 +357,7 @@ custom:
|
|
|
354
357
|
- name: someObjectInlineExample
|
|
355
358
|
summary: an example of a request
|
|
356
359
|
description: a longer string than the summary
|
|
357
|
-
value: {SomeObject: {SomeAttribute:
|
|
360
|
+
value: { SomeObject: { SomeAttribute: "attribute" } }
|
|
358
361
|
- name: someObjectExternalExample
|
|
359
362
|
summary: an example of a request external
|
|
360
363
|
description: a longer string than the summary
|
|
@@ -391,11 +394,11 @@ custom:
|
|
|
391
394
|
items: *ErrorItem
|
|
392
395
|
```
|
|
393
396
|
|
|
394
|
-
`&ErrorItem` in the above example creates a node anchor (&ErrorItem) to the `ErrorResponse` schema which then can be used in the `PutDocumentResponse` schema via the reference (
|
|
397
|
+
`&ErrorItem` in the above example creates a node anchor (&ErrorItem) to the `ErrorResponse` schema which then can be used in the `PutDocumentResponse` schema via the reference (\*ErrorItem). The node anchor needs to be declared first before it can be used elsewhere via the reference, swapping the above example around would result in an error.
|
|
395
398
|
|
|
396
399
|
##### ModelsList - Backwards compatibility
|
|
397
400
|
|
|
398
|
-
It was brought to my attention that an older plugin version allowed the use of `modelsList`.
|
|
401
|
+
It was brought to my attention that an older plugin version allowed the use of `modelsList`. As of 0.0.60, you can continue to use `modelsList` as well as using `models`, however `modelsList` now has to be nested within the `documentation` section. You can write `modelsList` the same way as any of the two styles for [Models](#Models).
|
|
399
402
|
|
|
400
403
|
```
|
|
401
404
|
custom:
|
|
@@ -412,7 +415,7 @@ custom:
|
|
|
412
415
|
|
|
413
416
|
##### Serverless Request Schema Validators
|
|
414
417
|
|
|
415
|
-
As of 0.0.64, you can now make use of [Request Schema Validators](https://www.serverless.com/framework/docs/providers/aws/events/apigateway#request-schema-validators).
|
|
418
|
+
As of 0.0.64, you can now make use of [Request Schema Validators](https://www.serverless.com/framework/docs/providers/aws/events/apigateway#request-schema-validators). This allows you to define Request models via the `apiGateway` settings:
|
|
416
419
|
|
|
417
420
|
```yml
|
|
418
421
|
provider:
|
|
@@ -439,11 +442,10 @@ functions:
|
|
|
439
442
|
request:
|
|
440
443
|
schemas:
|
|
441
444
|
application/json: post-create-model
|
|
442
|
-
documentation:
|
|
443
|
-
...
|
|
445
|
+
documentation: ...
|
|
444
446
|
```
|
|
445
447
|
|
|
446
|
-
The generator will match to the model within the `apiGateway` settings model list.
|
|
448
|
+
The generator will match to the model within the `apiGateway` settings model list. If you are using the `apiGateway` to define models, please do not re-use any names that you might define in the [`models`](#models) list.
|
|
447
449
|
|
|
448
450
|
You can also skip writing a `requestBody` and `requestModels` if you have defined a `request` property in your event.
|
|
449
451
|
|
|
@@ -462,8 +464,7 @@ functions:
|
|
|
462
464
|
application/json:
|
|
463
465
|
schema: ${file(create_request.json)}
|
|
464
466
|
name: PostCreateModel
|
|
465
|
-
description:
|
|
466
|
-
|
|
467
|
+
description: "Validation model for Creating Posts"
|
|
467
468
|
```
|
|
468
469
|
|
|
469
470
|
or
|
|
@@ -487,26 +488,27 @@ To define the documentation for a given function event, you need to create a `do
|
|
|
487
488
|
|
|
488
489
|
The `documentation` section of the event configuration can contain the following attributes:
|
|
489
490
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
491
|
+
- `summary`: A short description of the method
|
|
492
|
+
- `description`: A detailed description of the method
|
|
493
|
+
- `tags`: An array of tags for this event
|
|
494
|
+
- `deprecated`: Boolean indicator that indicates clients should migrate away from this function
|
|
495
|
+
- `requestBody`: Contains description of the request
|
|
496
|
+
- `description`: A description of the request body
|
|
497
|
+
- `required`: Whether the request body is required, defaults to false
|
|
498
|
+
- `requestModels`: A list of models to describe the request bodies (see [requestModels](#requestmodels) below)
|
|
499
|
+
- `queryParams`: A list of query parameters (see [queryParams](#queryparams) below)
|
|
500
|
+
- `pathParams`: A list of path parameters (see [pathParams](#pathparams) below)
|
|
501
|
+
- `cookieParams`: A list of cookie parameters (see [cookieParams](#cookieparams) below)
|
|
502
|
+
- `headerParams`: A list of headers (see [headerParams](#headerparams---request-headers) below)
|
|
503
|
+
- `security`: The security requirement to apply (see [security](#security) below)
|
|
504
|
+
- `methodResponses`: An array of response models and applicable status codes
|
|
505
|
+
- `statusCode`: Applicable http status code (ie. 200/404/500 etc.)
|
|
506
|
+
- `responseBody`: Contains description of the response
|
|
507
|
+
- `description`: A description of the body response
|
|
508
|
+
- `responseHeaders`: A list of response headers (see [responseHeaders](#responseheaders) below)
|
|
509
|
+
- `responseModels`: A list of models to describe the request bodies (see [responseModels](#responsemodels) below) for each `Content-Type`
|
|
510
|
+
|
|
511
|
+
If you don't want a `http` or `httpApi` event to be documented, you can leave off the `documentation` object. The configuration schema will only check that you have specified a `methodResponses` on the `documentation` event, previously the plugin would cause serverless to warn or error (depending on your `configValidationMode`) if you had not supplied a `documentation` on an event.
|
|
510
512
|
|
|
511
513
|
```yml
|
|
512
514
|
functions:
|
|
@@ -576,10 +578,10 @@ functions:
|
|
|
576
578
|
|
|
577
579
|
Query parameters can be described as follow:
|
|
578
580
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
581
|
+
- `name`: the name of the query variable
|
|
582
|
+
- `description`: a description of the query variable
|
|
583
|
+
- `required`: whether the query parameter is mandatory (boolean)
|
|
584
|
+
- `schema`: JSON schema (inline, file or externally hosted)
|
|
583
585
|
|
|
584
586
|
```yml
|
|
585
587
|
queryParams:
|
|
@@ -594,9 +596,9 @@ queryParams:
|
|
|
594
596
|
|
|
595
597
|
Path parameters can be described as follow:
|
|
596
598
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
599
|
+
- `name`: the name of the path parameter
|
|
600
|
+
- `description`: a description of the path parameter
|
|
601
|
+
- `schema`: JSON schema (inline, file or externally hosted)
|
|
600
602
|
|
|
601
603
|
```yml
|
|
602
604
|
pathParams:
|
|
@@ -610,10 +612,10 @@ pathParams:
|
|
|
610
612
|
|
|
611
613
|
Cookie parameters can be described as follow:
|
|
612
614
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
615
|
+
- `name`: the name of the cookie parameter
|
|
616
|
+
- `description`: a description of the cookie parameter
|
|
617
|
+
- `required`: whether the cookie parameter is mandatory (boolean)
|
|
618
|
+
- `schema`: JSON schema (inline, file or externally hosted)
|
|
617
619
|
|
|
618
620
|
```yml
|
|
619
621
|
cookieParams:
|
|
@@ -628,10 +630,10 @@ cookieParams:
|
|
|
628
630
|
|
|
629
631
|
Request Headers can be described as follow:
|
|
630
632
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
633
|
+
- `name`: the name of the header
|
|
634
|
+
- `description`: a description of the header
|
|
635
|
+
- `required`: whether the header is mandatory (boolean)
|
|
636
|
+
- `schema`: JSON schema (inline, file or externally hosted)
|
|
635
637
|
|
|
636
638
|
```yml
|
|
637
639
|
headerParams:
|
|
@@ -644,7 +646,7 @@ headerParams:
|
|
|
644
646
|
|
|
645
647
|
#### `security`
|
|
646
648
|
|
|
647
|
-
The `security` property allows you to specify the [Security Scheme](#securityschemes) to apply to the HTTP Request.
|
|
649
|
+
The `security` property allows you to specify the [Security Scheme](#securityschemes) to apply to the HTTP Request. If you have applied an `security` ([see Security on each operation](#security-on-each-operation)) then you can either leave this field off, or to override it with a different scheme you can write it like:
|
|
648
650
|
|
|
649
651
|
```yml
|
|
650
652
|
custom:
|
|
@@ -672,8 +674,8 @@ functions:
|
|
|
672
674
|
documentation:
|
|
673
675
|
security:
|
|
674
676
|
- petstore_auth:
|
|
675
|
-
|
|
676
|
-
|
|
677
|
+
- write:pets
|
|
678
|
+
- read:pets
|
|
677
679
|
```
|
|
678
680
|
|
|
679
681
|
If you have specified an `security` at the document root, but this HTTP Request should not apply any security schemes, you should set security to be an array with an empty object:
|
|
@@ -712,7 +714,7 @@ functions:
|
|
|
712
714
|
private: true
|
|
713
715
|
```
|
|
714
716
|
|
|
715
|
-
It will automatically setup an apiKey security scheme of `x-api-key` attached to that method.
|
|
717
|
+
It will automatically setup an apiKey security scheme of `x-api-key` attached to that method. You don't need to add this to the [Security Scheme](#securityschemes) in the main documentation. If you have already added a Security Scheme of an `apiKey` with a name of `x-api-key`, it will associate with that key.
|
|
716
718
|
|
|
717
719
|
```yml
|
|
718
720
|
custom:
|
|
@@ -732,8 +734,7 @@ functions:
|
|
|
732
734
|
path: /
|
|
733
735
|
method: get
|
|
734
736
|
private: true
|
|
735
|
-
documentation:
|
|
736
|
-
...
|
|
737
|
+
documentation: ...
|
|
737
738
|
```
|
|
738
739
|
|
|
739
740
|
Will set the Security Scheme to `my_api_key` for that operation.
|
|
@@ -789,7 +790,7 @@ responseModels:
|
|
|
789
790
|
|
|
790
791
|
##### `responseHeaders`
|
|
791
792
|
|
|
792
|
-
The `responseHeaders` property allows you to define the headers expected in a HTTP Response of the function event.
|
|
793
|
+
The `responseHeaders` property allows you to define the headers expected in a HTTP Response of the function event. This should only contain a description and a schema, which must be a JSON schema (inline, file or externally hosted).
|
|
793
794
|
|
|
794
795
|
```yml
|
|
795
796
|
responseHeaders:
|
|
@@ -801,15 +802,15 @@ responseHeaders:
|
|
|
801
802
|
|
|
802
803
|
###### CORS
|
|
803
804
|
|
|
804
|
-
You can automatically generate CORS response headers by setting `cors` at the function level.
|
|
805
|
+
You can automatically generate CORS response headers by setting `cors` at the function level. Serverless allows you to modify how CORS is setup, so you can have the default options with `cors: true`, or you can modify the settings as shown in the [serverless documentation for CORS](https://www.serverless.com/framework/docs/providers/aws/events/apigateway#enabling-cors).
|
|
805
806
|
|
|
806
|
-
The generator will interpret your settings for CORS and automatically add the response headers.
|
|
807
|
+
The generator will interpret your settings for CORS and automatically add the response headers. If for whatever reason you wish to override these, you can set them via the above `responseHeaders` setting and it'll apply your overrides.
|
|
807
808
|
|
|
808
809
|
##### OWASP
|
|
809
810
|
|
|
810
|
-
You can make use of the [OWASP Secure Headers](https://owasp.org/www-project-secure-headers/#x-permitted-cross-domain-policies) to generate response headers.
|
|
811
|
+
You can make use of the [OWASP Secure Headers](https://owasp.org/www-project-secure-headers/#x-permitted-cross-domain-policies) to generate response headers. These are a selection of response headers with default values that OWASP recommends returning with your response to help secure your application.
|
|
811
812
|
|
|
812
|
-
The OWASP Secure Headers Project contains a set of recommended headers to return with recommended values, when generating the documentation, the generator will attempt to get the latest version of this document and apply the latest recommendations.
|
|
813
|
+
The OWASP Secure Headers Project contains a set of recommended headers to return with recommended values, when generating the documentation, the generator will attempt to get the latest version of this document and apply the latest recommendations. If you do not allow outside connections, it will default to a version of recommendations from **2023-05-26 12:22:30 UTC**.
|
|
813
814
|
|
|
814
815
|
Like CORS, if you have already set any of the OWASP Secure headers via `responseHeaders`, it will not overwrite them.
|
|
815
816
|
|
|
@@ -827,7 +828,7 @@ methodResponse:
|
|
|
827
828
|
owasp: true
|
|
828
829
|
```
|
|
829
830
|
|
|
830
|
-
This will use the full set of OWASP Secure Headers and their recommended values.
|
|
831
|
+
This will use the full set of OWASP Secure Headers and their recommended values. Some of these might not be appropriate for your application.
|
|
831
832
|
|
|
832
833
|
###### Subset of OWASP Secure Headers
|
|
833
834
|
|
|
@@ -847,19 +848,19 @@ This will set only the `cacheControl` and `referrerPolicy` response header with
|
|
|
847
848
|
|
|
848
849
|
The full list of OWASP Secure Headers you can set are:
|
|
849
850
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
851
|
+
- cacheControl - Cache-Control,
|
|
852
|
+
- clearSiteData - Clear-Site-Data,
|
|
853
|
+
- contentSecurityPolicy - Content-Security-Policy,
|
|
854
|
+
- crossOriginEmbedderPolicy - Cross-Origin-Embedder-Policy,
|
|
855
|
+
- crossOriginOpenerPolicy - Cross-Origin-Opener-Policy,
|
|
856
|
+
- crossOriginResourcePolicy - Cross-Origin-Resource-Policy,
|
|
857
|
+
- permissionsPolicy - Permissions-Policy,
|
|
858
|
+
- pragma - Pragma,
|
|
859
|
+
- referrerPolicy - Referrer-Policy,
|
|
860
|
+
- strictTransportSecurity - Strict-Transport-Security,
|
|
861
|
+
- xContentTypeOptions - X-Content-Type-Options,
|
|
862
|
+
- xFrameOptions - X-Frame-Options,
|
|
863
|
+
- xPermittedCrossDomainPolicies - X-Permitted-Cross-Domain-Policies
|
|
863
864
|
|
|
864
865
|
###### Subset of OWASP Secure Headers with user defined values
|
|
865
866
|
|
|
@@ -885,7 +886,7 @@ Please view the example [serverless.yml](test/serverless-tests/serverless%202/se
|
|
|
885
886
|
|
|
886
887
|
## Notes on schemas
|
|
887
888
|
|
|
888
|
-
Schemas can be either: inline, in file or externally hosted.
|
|
889
|
+
Schemas can be either: inline, in file or externally hosted. If they're inline or in file, the plugin will attempt to normalise the schema to [OpenAPI 3.0.X specification](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#schemaObject).
|
|
889
890
|
|
|
890
891
|
If they exist as an external reference, for instance:
|
|
891
892
|
|
|
@@ -893,68 +894,70 @@ If they exist as an external reference, for instance:
|
|
|
893
894
|
schema: https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/bettercodehub.json
|
|
894
895
|
```
|
|
895
896
|
|
|
896
|
-
We use the plugin [JSON Schema $Ref Parser](https://apitools.dev/json-schema-ref-parser/) to attempt to parse and resolve the references.
|
|
897
|
+
We use the plugin [JSON Schema $Ref Parser](https://apitools.dev/json-schema-ref-parser/) to attempt to parse and resolve the references. There are limitations to this. Consider the schema:
|
|
897
898
|
|
|
898
899
|
```json
|
|
899
900
|
{
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
},
|
|
915
|
-
"link" : {"$refs": "./properties.json#/properties/title"}
|
|
901
|
+
"$schema": "https://json-schema.org/draft-04/schema",
|
|
902
|
+
"title": "Reusable Definitions",
|
|
903
|
+
"type": "object",
|
|
904
|
+
"id": "https://raw.githubusercontent.com/json-editor/json-editor/master/tests/fixtures/definitions.json",
|
|
905
|
+
"definitions": {
|
|
906
|
+
"address": {
|
|
907
|
+
"title": "Address",
|
|
908
|
+
"type": "object",
|
|
909
|
+
"properties": {
|
|
910
|
+
"street_address": { "type": "string" },
|
|
911
|
+
"city": { "type": "string" },
|
|
912
|
+
"state": { "type": "string" }
|
|
913
|
+
},
|
|
914
|
+
"required": ["street_address"]
|
|
916
915
|
},
|
|
917
|
-
"
|
|
918
|
-
|
|
919
|
-
|
|
916
|
+
"link": { "$refs": "./properties.json#/properties/title" }
|
|
917
|
+
},
|
|
918
|
+
"properties": {
|
|
919
|
+
"address": { "$refs": "#/definitions/address" }
|
|
920
920
|
}
|
|
921
|
+
}
|
|
921
922
|
```
|
|
923
|
+
|
|
922
924
|
Where the definition "link" refers to a schema held in a directory that the resolver does not know about, we will not be able to fully resolve the schema which will likely cause errors in validation of the openAPI 3.0.X specification.
|
|
923
925
|
|
|
924
926
|
Because of the dependency we use to parse externally linked schemas, we can supply our own options to resolve schemas that are more difficult than a straight forward example.
|
|
925
927
|
|
|
926
|
-
You can create your own options file: https://apitools.dev/json-schema-ref-parser/docs/options.html to pass into the dependency that contains it's own resolver to allow you to resolve references that might be in hard to reach places.
|
|
928
|
+
You can create your own options file: https://apitools.dev/json-schema-ref-parser/docs/options.html to pass into the dependency that contains it's own resolver to allow you to resolve references that might be in hard to reach places. In your main project folder, you should have a folder called `options` with a file called `ref-parser.js` that looks like:
|
|
927
929
|
|
|
928
930
|
```js
|
|
929
|
-
|
|
931
|
+
"use strict";
|
|
930
932
|
|
|
931
933
|
// options from: https://apitools.dev/json-schema-ref-parser/docs/options.html
|
|
932
934
|
|
|
933
935
|
module.exports = {
|
|
934
|
-
continueOnError: true,
|
|
936
|
+
continueOnError: true, // Don't throw on the first error
|
|
935
937
|
parse: {
|
|
936
|
-
json: false,
|
|
938
|
+
json: false, // Disable the JSON parser
|
|
937
939
|
yaml: {
|
|
938
|
-
allowEmpty: false
|
|
940
|
+
allowEmpty: false, // Don't allow empty YAML files
|
|
939
941
|
},
|
|
940
942
|
text: {
|
|
941
|
-
canParse: [".txt", ".html"],
|
|
942
|
-
encoding:
|
|
943
|
-
}
|
|
943
|
+
canParse: [".txt", ".html"], // Parse .txt and .html files as plain text (strings)
|
|
944
|
+
encoding: "utf16", // Use UTF-16 encoding
|
|
945
|
+
},
|
|
944
946
|
},
|
|
945
947
|
resolve: {
|
|
946
|
-
file: false,
|
|
948
|
+
file: false, // Don't resolve local file references
|
|
947
949
|
http: {
|
|
948
|
-
timeout: 2000,
|
|
949
|
-
withCredentials: true,
|
|
950
|
-
}
|
|
950
|
+
timeout: 2000, // 2 second timeout
|
|
951
|
+
withCredentials: true, // Include auth credentials when resolving HTTP references
|
|
952
|
+
},
|
|
951
953
|
},
|
|
952
954
|
dereference: {
|
|
953
|
-
circular: false,
|
|
954
|
-
excludedPathMatcher: (
|
|
955
|
-
path
|
|
956
|
-
|
|
957
|
-
}
|
|
955
|
+
circular: false, // Don't allow circular $refs
|
|
956
|
+
excludedPathMatcher: (
|
|
957
|
+
path // Skip dereferencing content under any 'example' key
|
|
958
|
+
) => path.includes("/example/"),
|
|
959
|
+
},
|
|
960
|
+
};
|
|
958
961
|
```
|
|
959
962
|
|
|
960
963
|
If you don't supply this file, it will use the default options.
|
package/package.json
CHANGED
|
@@ -348,7 +348,8 @@ class DefinitionGenerator {
|
|
|
348
348
|
requestModel,
|
|
349
349
|
{
|
|
350
350
|
description: documentation.requestBody.description,
|
|
351
|
-
models: documentation.requestModels
|
|
351
|
+
models: documentation.requestModels,
|
|
352
|
+
required: documentation.requestBody.required
|
|
352
353
|
}
|
|
353
354
|
)
|
|
354
355
|
} else {
|
|
@@ -511,7 +512,7 @@ class DefinitionGenerator {
|
|
|
511
512
|
async createRequestBody(requestBodyDetails) {
|
|
512
513
|
const obj = {
|
|
513
514
|
description: requestBodyDetails.description,
|
|
514
|
-
required: false
|
|
515
|
+
required: requestBodyDetails.required || false
|
|
515
516
|
}
|
|
516
517
|
|
|
517
518
|
obj.content = await this.createMediaTypeObject(requestBodyDetails.models)
|