{"id":15286034,"url":"https://github.com/jaredce/serverless-openapi-documenter","last_synced_at":"2025-04-05T04:13:05.075Z","repository":{"id":37613143,"uuid":"495583813","full_name":"JaredCE/serverless-openapi-documenter","owner":"JaredCE","description":"Serverless plugin to export your config as OpenAPI v3 Documentation and Postman Collection V2","archived":false,"fork":false,"pushed_at":"2025-04-04T14:24:32.000Z","size":907,"stargazers_count":43,"open_issues_count":15,"forks_count":13,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T04:12:59.668Z","etag":null,"topics":["openapi","openapi-documentation","openapi-generator","openapi3","serverless","serverless-framework"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JaredCE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-23T21:49:03.000Z","updated_at":"2025-04-02T11:30:59.000Z","dependencies_parsed_at":"2023-09-25T15:46:04.676Z","dependency_job_id":"67b49b6b-f371-46aa-aa59-1f3fa82f62d1","html_url":"https://github.com/JaredCE/serverless-openapi-documenter","commit_stats":{"total_commits":356,"total_committers":5,"mean_commits":71.2,"dds":0.0730337078651685,"last_synced_commit":"d4380599b04b8efd59059e6dc0cb830471e63a39"},"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredCE%2Fserverless-openapi-documenter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredCE%2Fserverless-openapi-documenter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredCE%2Fserverless-openapi-documenter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaredCE%2Fserverless-openapi-documenter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JaredCE","download_url":"https://codeload.github.com/JaredCE/serverless-openapi-documenter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284951,"owners_count":20913704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openapi","openapi-documentation","openapi-generator","openapi3","serverless","serverless-framework"],"created_at":"2024-09-30T15:10:15.194Z","updated_at":"2025-04-05T04:13:05.057Z","avatar_url":"https://github.com/JaredCE.png","language":"JavaScript","readme":"# OpenAPI Generator for serverless\n\n\u003cp\u003e\n  \u003ca href=\"https://www.serverless.com\"\u003e\n    \u003cimg src=\"http://public.serverless.com/badges/v3.svg\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/serverless-openapi-documenter\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/serverless-openapi-documenter.svg?style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/JaredCE/serverless-openapi-documenter/actions/workflows/node.yml\"\u003e\n    \u003cimg src=\"https://github.com/JaredCE/serverless-openapi-documenter/actions/workflows/node.yml/badge.svg\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nThis will generate an OpenAPI V3 (up to v3.0.4) 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.\n\nOriginally based off of: https://github.com/temando/serverless-openapi-documentation\n\n## Install\n\nThis plugin works for Serverless (2.x, 3.x and 4.x) and only supports node.js 20 and up.\n\nTo add this plugin to your package.json:\n\n**Using npm:**\n\n```bash\nnpm install --save-dev serverless-openapi-documenter\n```\n\nNext you need to add the plugin to the `plugins` section of your `serverless.yml` file.\n\n```yml\nplugins:\n  - serverless-openapi-documenter\n```\n\n\u003e Note: Add this plugin _after_ `serverless-offline` to prevent issues with `String.replaceAll` being overridden incorrectly.\n\n## Adding documentation to serverless\n\nTo Run: `serverless openapi generate -o openapi.json -f json -a 3.0.4 -p postman.json`\n\nOptions:\n\n```\n--output                -o  What filename the OpenAPI Description should output under. Default: openapi.json\n--format                -f  Whether to output the OpenAPI Description as json or yaml. Default: json\n--indent                -i  File indentation in spaces. Default: 2\n--openApiVersion        -a  OpenAPI version to generate for. Default: 3.0.0\n--postmanCollection     -p  Will generate a postman collection (from the generated OpenAPI Description), in json only, if passed in. Default: postman.json\n--validationWarn        -w  Warn about validation errors only.  Will write the OpenAPI file if generation is successful.  Default: false\n```\n\n### README Highlighted Reading\n\n#### Security Details\n\n- [Security](#securityschemes)\n- [Security on All Operations](#security-on-each-operation)\n- [Security Per Operation](#security)\n\n#### Model Details\n\n- [Models](#models)\n- [Notes on Schemas](#notes-on-schemas)\n- [Request Schema Validators](#serverless-request-schema-validators)\n\n#### Response Headers\n\n- [CORS](#cors)\n- [OWASP Secure Headers](#owasp)\n\n#### Validation\n\n- [Validation](#validator)\n\n### OpenAPI Mapping\n\n| OpenAPI field                                             | Serverless field                                                                                                                                      |\n| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| info.title                                                | `custom.documentation.title` OR service                                                                                                               |\n| info.description                                          | `custom.documentation.description` OR blank string                                                                                                    |\n| info.version                                              | `custom.documentation.version` OR random v4 uuid if not provided                                                                                      |\n| info.termsOfService                                       | `custom.documentation.termsOfService`                                                                                                                 |\n| info.contact                                              | custom.documentation.contact                                                                                                                          |\n| info.contact.name                                         | `custom.documentation.contact.name` OR blank string                                                                                                   |\n| info.contact.url                                          | `custom.documentation.contact.url` if provided                                                                                                        |\n| info.contact.x-                                           | `custom.documentation.contact.x-` extended specifications provided                                                                                    |\n| info.license                                              | custom.documentation.license                                                                                                                          |\n| info.license.name                                         | `custom.documentation.license.name` OR blank string                                                                                                   |\n| info.license.url                                          | `custom.documentation.license.url` if provided                                                                                                        |\n| info.license.x-                                           | `custom.documentation.license.x-` if extended specifications provided provided                                                                        |\n| externalDocs.description                                  | `custom.documentation.externalDocumentation.description `                                                                                             |\n| externalDocs.url                                          | `custom.documentation.externalDocumentation.url`                                                                                                      |\n| x-tagGroups                                               | `custom.documentation.x-tagGroups` if provided                                                                                                        |\n| security                                                  | `custom.documentation.security`                                                                                                                       |\n| servers[].description                                     | custom.documentation.servers.description                                                                                                              |\n| servers[].url                                             | custom.documentation.servers.url                                                                                                                      |\n| servers[].variables                                       | custom.documentation.servers.variables                                                                                                                |\n| tags[].name                                               | `custom.documentation.tags.name`                                                                                                                      |\n| tags[].description                                        | `custom.documentation.tags.description`                                                                                                               |\n| tags[].externalDocs.url                                   | `custom.documentation.tags.externalDocumentation.url`                                                                                                 |\n| tags[].externalDocs.description                           | `custom.documentation.tags.externalDocumentation.description`                                                                                         |\n| tags[].externalDocs.x-                                    | `custom.documentation.tags.externalDocumentation.x-` if extended specifications provided                                                              |\n| path[path]                                                | functions.functions.events.[http OR httpApi].path                                                                                                     |\n| path[path].servers[].description                          | functions.functions.servers.description                                                                                                               |\n| path[path].servers[].url                                  | functions.functions.servers.url                                                                                                                       |\n| path[path].[operation]                                    | functions.functions.[http OR httpApi].method                                                                                                          |\n| path[path].[operation].summary                            | functions.functions.[http OR httpApi].documentation.summary                                                                                           |\n| path[path].[operation].description                        | functions.functions.[http OR httpApi].documentation.description                                                                                       |\n| path[path].[operation].operationId                        | functions.functions.[http OR httpApi].documentation.operationId OR functionName                                                                       |\n| path[path].[operation].deprecated                         | functions.functions.[http OR httpApi].documentation.deprecated                                                                                        |\n| path[path].[operation].externalDocs.description           | functions.functions.[http OR httpApi].documentation.externalDocumentation.description                                                                 |\n| path[path].[operation].externalDocs.url                   | functions.functions.[http OR httpApi].documentation.externalDocumentation.url                                                                         |\n| path[path].[operation].servers[].description              | functions.functions.[http OR httpApi].documentation.servers.description                                                                               |\n| path[path].[operation].servers[].url                      | functions.functions.[http OR httpApi].documentation.servers.url                                                                                       |\n| path[path].[operation].security                           | functions.functions.[http OR httpApi].documentation.security                                                                                          |\n| path[path].[operation].deprecated                         | functions.functions.[http OR httpApi].documentation.deprecated                                                                                        |\n| path[path].[operation].parameters                         | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params                                                                  |\n| path[path].[operation].parameters.name                    | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.name                                                             |\n| path[path].[operation].parameters.in                      | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params                                                                  |\n| path[path].[operation].parameters.description             | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.description                                                      |\n| path[path].[operation].parameters.required                | functions.functions.[http OR httpApi].documentation.[query/cookie/header]Params.required                                                              |\n| path[path].[operation].parameters.deprecated              | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.deprecated                                                       |\n| path[path].[operation].parameters.allowEmptyValue         | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.allowEmptyValue                                                  |\n| path[path].[operation].parameters.style                   | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.style                                                            |\n| path[path].[operation].parameters.explode                 | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.explode                                                          |\n| path[path].[operation].parameters.allowReserved           | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.allowReserved                                                    |\n| path[path].[operation].parameters.schema                  | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.schema                                                           |\n| path[path].[operation].parameters.example                 | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.example                                                          |\n| path[path].[operation].parameters.examples                | functions.functions.[http OR httpApi].documentation.[path/query/cookie/header]Params.examples                                                         |\n| path[path].[operation].requestBody                        | functions.functions.[http OR httpApi].documentation.requestBody                                                                                       |\n| path[path].[operation].requestBody.description            | functions.functions.[http OR httpApi].documentation.requestBody.description                                                                           |\n| path[path].[operation].requestBody.required               | functions.functions.[http OR httpApi].documentation.requestBody.required                                                                              |\n| path[path].[operation].requestBody.content                | functions.functions.[http OR httpApi].documentation.requestModels[contentType].name Links to custom.documentation.models.name                         |\n| path[path].[operation].responses                          | functions.functions.[http OR httpApi].documentation.methodResponses                                                                                   |\n| path[path].[operation].responses.[statusCode]             | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode]                                                                       |\n| path[path].[operation].responses.[statusCode].description | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseBody.description                                              |\n| path[path].[operation].responses.[statusCode].content     | functions.functions.[http OR httpApi].documentation.methodResponses[statusCode].responseModels[contentType] Links to custom.documentation.models.name |\n\n### Configuration\n\nTo configure this plugin to generate a valid OpenAPI Description, there are two places you'll need to modify in your `serverless.yml` file, the `custom` variables section and the `http/httpApi` event section for each given function in your service.\n\nThe `custom` section of your `serverless.yml` can be configured as below:\n\n```yml\ncustom:\n  documentation:\n    version: \"1\"\n    title: \"My API\"\n    description: \"This is my API\"\n    termsOfService: https://google.com\n    externalDocumentation:\n      url: https://google.com\n      description: A link to google\n    servers:\n      url: https://example.com:{port}/\n      description: The server\n      variables:\n        port:\n          enum:\n            - 4000\n            - 3000\n          default: 3000\n          description: The port the server operates on\n    tags:\n      - name: tag1\n        description: this is a tag\n        externalDocumentation:\n          url: https://npmjs.com\n          description: A link to npm\n    models: {}\n```\n\nMostly 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.\n\n#### termsOfService\n\nMust be in the format of a url if included.\n\n#### Contact\n\nYou can provide an optional contact object such as:\n\n```yml\ncustom:\n  documentation:\n    contact:\n      name: John\n      url: https://example.com\n      email: John@example.com\n```\n\nThese fields are optional, though `url` needs to in the form of a URL and `email` needs to be in the format of an email address (ed: what that might be, I'm not 100% sure... go read the email RFC(s)).\n\nThis can be extended using the `^x-` specification extension.\n\n#### License\n\nYou can provide an optional license object such as:\n\n```yml\ncustom:\n  documentation:\n    license:\n      name: Apache 2.0\n      url: https://www.apache.org/licenses/LICENSE-2.0.html\n```\n\nName is required but `url` is optional and must be in the format of a url.\n\nThis can be extended using the `^x-` specification extension.\n\n#### Extended Fields\n\nYou can also add extended fields to the documentation object:\n\n```yml\ncustom:\n  documentation:\n    x-other-field: This is an extended field\n```\n\nThese fields must have `x-` before them, otherwise they will be ignored:\n\n```yml\ncustom:\n  documentation:\n    other-field: This is an extended field\n```\n\n`other-field` here will not make it to the generated OpenAPI schema.\n\nCurrently extended specification fields defined under the `documentation` tag will sit under the OpenAPI `info` object e.g.\n\n```yml\ncustom:\n  documentation:\n    title: myService\n    x-other-field: This is an extended field\n```\n\nconverts to:\n\n```json\n{\n  \"info\": {\n    \"title\": \"myService\",\n    \"x-other-field\": \"This is an extended field\"\n  }\n}\n```\n\nAn exception to this is Redocly `x-tagGroups`. If defined, they will sit at the root level of the OpenAPI specification, e.g.\n\n```yml\ncustom:\n  documentation:\n    title: myService\n    x-other-field: This is an extended field\n    x-tagGroups:\n      - name: Customers\n        tags:\n          - Customers\n```\n\nconverts to:\n\n```json\n{\n  \"info\": {\n    \"title\": \"myService\",\n    \"x-other-field\": \"This is an extended field\"\n  },\n  \"x-tagGroups\": [\n    {\n      \"name\": \"Customers\",\n      \"tags\": [\"Customers\"]\n    }\n  ]\n}\n```\n\n#### Moving documentation to a separate file\n\nThese configurations can be quite verbose; you can separate it out into it's own file, such as `serverless.doc.yml` as below:\n\n```yml\ncustom:\n  documentation: ${file(serverless.doc.yml):documentation}\n\nfunctions:\n  myFunc:\n    events:\n      - http:\n          path: getStuff\n          method: get\n          documentation: ${file(serverless.doc.yml):endpoints.myFunc}\n```\n\nFor more info on `serverless.yml` syntax, see their docs.\n\n#### securitySchemes\n\nYou can provide optional Security Schemes:\n\n```yml\ncustom:\n  documentation:\n    securitySchemes:\n      my_api_key:\n        type: apiKey\n        name: api_key\n        in: header\n```\n\nIt accepts all available Security Schemes and follows the specification: https://spec.openapis.org/oas/v3.0.4#security-scheme-object\n\n#### Security on each operation\n\nTo apply an overall security scheme to all of your operations without having to add the documentation to each one, you can write it like:\n\n```yml\ncustom:\n  documentation:\n    securitySchemes:\n      my_api_key:\n        type: apiKey\n        name: api_key\n        in: header\n    security:\n      - my_api_key: []\n```\n\nThis will apply the requirement of each operation requiring your `my_api_key` security scheme, [you can override this](#security).\n\n#### Models\n\nThere 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.\n\nThe first way of writing the model is:\n_required_ directives for the models section are as follow:\n\n- `name`: the name of the schema\n- `description`: a description of the schema\n- `contentType`: the content type of the described request/response (ie. `application/json` or `application/xml`).\n- `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.\n\n```yml\ncustom:\n  documentation:\n    models:\n      - name: \"ErrorResponse\"\n        description: \"This is an error\"\n        contentType: \"application/json\"\n        schema: ${file(models/ErrorResponse.json)}\n      - name: \"PutDocumentResponse\"\n        description: \"PUT Document response model (external reference example)\"\n        contentType: \"application/json\"\n        schema: ${file(models/PutDocumentResponse.json)}\n      - name: \"PutDocumentRequest\"\n        description: \"PUT Document request model (inline example)\"\n        contentType: \"application/json\"\n        schema:\n          $schema: \"http://json-schema.org/draft-04/schema#\"\n          type: object\n          properties:\n            SomeObject:\n              type: \"object\"\n              properties:\n                SomeAttribute:\n                  type: \"string\"\n        examples:\n          - name: someObjectInlineExample\n            summary: an example of a request\n            description: a longer string than the summary\n            value: { SomeObject: { SomeAttribute: \"attribute\" } }\n          - name: someObjectExternalExample\n            summary: an example of a request external\n            description: a longer string than the summary\n            externalValue: https://example.com/external.json\n```\n\nThe Second way of writing the models:\n\n- `name`: the name of the schema\n- `description`: a description of the schema\n- `content`: an Object made up of the contentType and the schema, as shown below\n\n```yml\ncustom:\n  documentation:\n    models:\n      - name: \"ErrorResponse\"\n        description: \"This is an error\"\n        content:\n          application/json:\n            schema: ${file(models/ErrorResponse.json)}\n      - name: \"PutDocumentResponse\"\n        description: \"PUT Document response model (external reference example)\"\n        content:\n          application/json:\n            schema: ${file(models/PutDocumentResponse.json)}\n      - name: \"PutDocumentRequest\"\n        description: \"PUT Document request model (inline example)\"\n        content:\n          application/json:\n            schema:\n              $schema: \"http://json-schema.org/draft-04/schema#\"\n              type: object\n              properties:\n                SomeObject:\n                  type: \"object\"\n                  properties:\n                    SomeAttribute:\n                      type: \"string\"\n            examples:\n              - name: someObjectInlineExample\n                summary: an example of a request\n                description: a longer string than the summary\n                value: { SomeObject: { SomeAttribute: \"attribute\" } }\n              - name: someObjectExternalExample\n                summary: an example of a request external\n                description: a longer string than the summary\n                externalValue: https://example.com/external.json\n```\n\n##### Model re-use\n\nThrough the magic of YAML, you can re-use models:\n\n```yml\ncustom:\n  documentation:\n    ...\n    models:\n      - name: \"ErrorResponse\"\n        description: \"This is an error\"\n        content:\n          application/json:\n            schema: \u0026ErrorItem\n              type: object\n              properties:\n                message:\n                  type: string\n                code:\n                  type: integer\n\n      - name: \"PutDocumentResponse\"\n        description: \"PUT Document response model (external reference example)\"\n        content:\n          application/json:\n            schema:\n              type: array\n              items: *ErrorItem\n```\n\n`\u0026ErrorItem` in the above example creates a node anchor (\u0026ErrorItem) 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.\n\n##### ModelsList - Backwards compatibility\n\nIt 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).\n\n```\ncustom:\n  documentation:\n    ...\n    modelsList:\n      - name: \"ErrorResponse\"\n        description: \"This is an error\"\n        content:\n          application/json:\n            schema:\n              type: string\n```\n\n##### Serverless Request Schema Validators\n\nAs 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:\n\n```yml\nprovider:\n  ...\n  apiGateway:\n    request:\n      schemas:\n        post-create-model:\n          name: PostCreateModel\n          schema: ${file(api_schema/post_add_schema.json)}\n          description: \"A Model validation for adding posts\"\n```\n\nwhich are then used like:\n\n```yml\nfunctions:\n  create:\n    handler: posts.create\n    events:\n      - http:\n          path: posts/create\n          method: post\n          request:\n            schemas:\n              application/json: post-create-model\n          documentation: ...\n```\n\nThe 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.\n\nYou can also skip writing a `requestBody` and `requestModels` if you have defined a `request` property in your event.\n\nIf you're not using `apiGateway`, you can still make use of `request` by writing in the other styles that serverless accepts for Request Schema Validators:\n\n```yml\nfunctions:\n  create:\n    handler: posts.create\n    events:\n      - http:\n          path: posts/create\n          method: post\n          request:\n            schemas:\n              application/json:\n                schema: ${file(create_request.json)}\n                name: PostCreateModel\n                description: \"Validation model for Creating Posts\"\n```\n\nor\n\n```yml\nfunctions:\n  create:\n    handler: posts.create\n    events:\n      - http:\n          path: posts/create\n          method: post\n          request:\n            schemas:\n              application/json: ${file(create_request.json)}\n```\n\n#### Functions\n\nTo define the documentation for a given function event, you need to create a `documentation` attribute for your `http` or `httpApi` event in your `serverless.yml` file.\n\nThe `documentation` section of the event configuration can contain the following attributes:\n\n- `summary`: A short description of the method\n- `description`: A detailed description of the method\n- `tags`: An array of tags for this event\n- `deprecated`: Boolean indicator that indicates clients should migrate away from this function\n- `requestBody`: Contains description of the request\n  - `description`: A description of the request body\n  - `required`: Whether the request body is required, defaults to false\n- `requestModels`: A list of models to describe the request bodies (see [requestModels](#requestmodels) below)\n- `queryParams`: A list of query parameters (see [queryParams](#queryparams) below)\n- `pathParams`: A list of path parameters (see [pathParams](#pathparams) below)\n- `cookieParams`: A list of cookie parameters (see [cookieParams](#cookieparams) below)\n- `headerParams`: A list of headers (see [headerParams](#headerparams---request-headers) below)\n- `security`: The security requirement to apply (see [security](#security) below)\n- `methodResponses`: An array of response models and applicable status codes\n  - `statusCode`: Applicable http status code (ie. 200/404/500 etc.)\n  - `responseBody`: Contains description of the response\n    - `description`: A description of the body response\n  - `responseHeaders`: A list of response headers (see [responseHeaders](#responseheaders) below)\n  - `responseModels`: A list of models to describe the request bodies (see [responseModels](#responsemodels) below) for each `Content-Type`\n\nIf 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.\n\n```yml\nfunctions:\n  createUser:\n    handler: handler.create\n    events:\n      - http:\n        path: create\n        method: post\n        cors: true\n        summary:\n        documentation:\n          summary: \"Create User\"\n          description: \"Creates a user and then sends a generated password email\"\n          tags:\n            - tag1\n          externalDocumentation:\n            url: https://bing.com\n            description: A link to bing\n          requestBody:\n            description: \"A user information object\"\n          requestModels:\n            application/json: \"PutDocumentRequest\"\n          pathParams:\n            - name: \"username\"\n              description: \"The username for a user to create\"\n              schema:\n                type: \"string\"\n                pattern: \"^[-a-z0-9_]+$\"\n          queryParams:\n            - name: \"membershipType\"\n              description: \"The user's Membership Type\"\n              schema:\n                type: \"string\"\n                enum:\n                  - \"premium\"\n                  - \"standard\"\n          cookieParams:\n            - name: \"SessionId\"\n              description: \"A Session ID variable\"\n              schema:\n                type: \"string\"\n          headerParams:\n            name: \"Content-Type\"\n            description: \"The content type\"\n            schema:\n              type: \"string\"\n          methodResponses:\n            - statusCode: 201\n              responseBody:\n                description: \"A user object along with generated API Keys\"\n              responseModels:\n                application/json: \"PutDocumentResponse\"\n              responseHeaders:\n                X-Rate-Limit-Limit:\n                  description: The number of allowed requests in the current period\n                  schema:\n                    type: integer\n            - statusCode: 500\n              responseBody:\n                description: \"An error message when creating a new user\"\n              responseModels:\n                application/json: \"ErrorResponse\"\n```\n\n#### `queryParams`\n\nQuery parameters can be described as follow:\n\n- `name`: the name of the query variable\n- `description`: a description of the query variable\n- `required`: whether the query parameter is mandatory (boolean)\n- `schema`: JSON schema (inline, file or externally hosted)\n\n```yml\nqueryParams:\n  - name: \"filter\"\n    description: \"The filter parameter\"\n    required: true\n    schema:\n      type: \"string\"\n```\n\n#### `pathParams`\n\nPath parameters can be described as follow:\n\n- `name`: the name of the path parameter\n- `description`: a description of the path parameter\n- `schema`: JSON schema (inline, file or externally hosted)\n\n```yml\npathParams:\n  - name: \"usernameId\"\n    description: \"The usernameId parameter\"\n    schema:\n      type: \"string\"\n```\n\n#### `cookieParams`\n\nCookie parameters can be described as follow:\n\n- `name`: the name of the cookie parameter\n- `description`: a description of the cookie parameter\n- `required`: whether the cookie parameter is mandatory (boolean)\n- `schema`: JSON schema (inline, file or externally hosted)\n\n```yml\ncookieParams:\n  - name: \"sessionId\"\n    description: \"The sessionId parameter\"\n    required: true\n    schema:\n      type: \"string\"\n```\n\n#### `headerParams` - Request Headers\n\nRequest Headers can be described as follow:\n\n- `name`: the name of the header\n- `description`: a description of the header\n- `required`: whether the header is mandatory (boolean)\n- `schema`: JSON schema (inline, file or externally hosted)\n\n```yml\nheaderParams:\n  - name: \"Content-Type\"\n    description: \"The content type\"\n    required: true\n    schema:\n      type: \"string\"\n```\n\n#### `security`\n\nThe `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:\n\n```yml\ncustom:\n  documentation:\n    securitySchemes:\n      my_api_key:\n        type: apiKey\n        name: api_key\n        in: header\n      petstore_auth:\n        type: oauth2\n        flows:\n          implicit:\n            authorizationUrl: https://example.com/api/oauth/dialog\n            scopes:\n              write:pets: modify pets in your account\n              read:pets: read your pets\n    security:\n      - my_api_key: []\n\nfunctions:\n  getData:\n    events:\n      - http:\n          documentation:\n            security:\n              - petstore_auth:\n                  - write:pets\n                  - read:pets\n```\n\nIf 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:\n\n```yml\ncustom:\n  documentation:\n    securitySchemes:\n      my_api_key:\n        type: apiKey\n        name: api_key\n        in: header\n    security:\n      - my_api_key: []\n\nfunctions:\n  getData:\n    events:\n      - http:\n          documentation:\n            security:\n              - {}\n```\n\n##### private\n\nIf you use the [private](https://www.serverless.com/framework/docs/providers/aws/events/apigateway#setting-api-keys-for-your-rest-api) property on your event:\n\n```yml\nfunctions:\n  getData:\n    events:\n      - http:\n          path: /\n          method: get\n          private: true\n```\n\nIt 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.\n\n```yml\ncustom:\n  documentation:\n    securitySchemes:\n      my_api_key:\n        type: apiKey\n        name: x-api-key\n        in: header\n    security:\n      - my_api_key: []\n\nfunctions:\n  getData:\n    events:\n      - http:\n          path: /\n          method: get\n          private: true\n          documentation: ...\n```\n\nWill set the Security Scheme to `my_api_key` for that operation.\n\n#### `requestModels`\n\nThe `requestModels` property allows you to define models for the HTTP Request of the function event. You can define a different model for each different `Content-Type`. You can define a reference to the relevant request model named in the `models` section of your configuration (see [Defining Models](#models) section).\n\n```yml\nrequestModels:\n  application/json: \"CreateRequest\"\n  application/xml: \"CreateRequestXML\"\n```\n\n#### `methodResponses`\n\n`methodResponses` is a mandatory property and should include the `responseBody` and `description` properties.\n\nYou can define the response schemas by defining properties for your function event.\n\nFor an example of a `methodResponses` configuration for an event see below:\n\n```yml\nmethodResponse:\n  - statusCode: 200\n    responseBody:\n      description: Success\n    responseModels:\n      application/json: \"CreateResponse\"\n      application/xml: \"CreateResponseXML\"\n    links:\n      getDataLink:\n        operation: getData\n        description: The id created here can be used to get Data\n        parameters:\n          contentId: $response.body#/id\n    responseHeaders:\n      X-Rate-Limit-Limit:\n        description: The number of allowed requests in the current period\n        schema:\n          type: integer\n      X-Rate-Limit-Remaining:\n        description: The number of remaining requests in the current period\n        schema:\n          type: integer\n      X-Rate-Limit-Reset:\n        description: The number of seconds left in the current period\n        schema:\n          type: integer\n```\n\n##### `responseModels`\n\nThe `responseModels` property allows you to define models for the HTTP Response of the function event. You can define a different model for each different `Content-Type`. You can define a reference to the relevant response model named in the `models` section of your configuration (see [Defining Models](#models) section).\n\n```yml\nresponseModels:\n  application/json: \"CreateResponse\"\n  application/xml: \"CreateResponseXML\"\n```\n\n##### `links`\n\nThe `links` property allows you to define how operations are linked to each other:\n\n```yml\nlinks:\n  linkName:\n    operation: getContent\n    description: The contentId created here can be used to get content\n    parameters:\n      contentId: $response.body#/contentId\n```\n\nWhere we are specifying operation, this should map to the function name:\n\n```yml\nfunctions:\n  createContent:\n    events:\n      - httpApi:\n          path: /\n          method: POST\n          documentation: ...\n  getContent:\n    events:\n      - http:\n          path: /{contentId}\n          method: POST\n          documentation: ...\n```\n\nIf our example link was attached to the **createContent** function, and we wanted the `contentId` that was created to be used on the **getContent** function in the `contentId` parameter, we'd specify the `operation` property as **getContent**. If however, you had specified an operationId in the documentation to override the automatically created one:\n\n```yml\ngetContent:\n  events:\n    - http:\n        path: /{contentId}\n        method: POST\n        documentation:\n          operationId: getMyContent\n```\n\nYou can refer to the `operationId` that you created.\n\nYou can read more about [links](https://swagger.io/docs/specification/links/) on the swagger.io site and in the [OpenAPI](https://spec.openapis.org/oas/v3.0.4#link-object) specification. They don't seem widely supported just yet, but perhaps they'll improve your documentation.\n\n##### `responseHeaders`\n\nThe `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).\n\n```yml\nresponseHeaders:\n  X-Rate-Limit-Limit:\n    description: The number of allowed requests in the current period\n    schema:\n      type: integer\n```\n\n###### CORS\n\nYou 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).\n\nThe 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.\n\n##### OWASP\n\nYou 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.\n\nThe 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 **2024-09-19 21:29:28 UTC**.\n\nLike CORS, if you have already set any of the OWASP Secure headers via `responseHeaders`, it will not overwrite them.\n\nTo make use of OWASP Secure Headers, you can use the following:\n\n###### All OWASP Secure Headers\n\n```yml\nmethodResponse:\n  - statusCode: 200\n    responseBody:\n      description: Success\n    responseModels:\n      application/json: \"CreateResponse\"\n    owasp: true\n```\n\nThis will use the full set of OWASP Secure Headers and their recommended values. Some of these might not be appropriate for your application.\n\n###### Subset of OWASP Secure Headers\n\n```yml\nmethodResponse:\n  - statusCode: 200\n    responseBody:\n      description: Success\n    responseModels:\n      application/json: \"CreateResponse\"\n    owasp:\n      cacheControl: true\n      referrerPolicy: true\n```\n\nThis will set only the `cacheControl` and `referrerPolicy` response header with the default recommendations.\n\nThe full list of OWASP Secure Headers you can set are:\n\n- cacheControl - Cache-Control,\n- clearSiteData - Clear-Site-Data,\n- contentSecurityPolicy - Content-Security-Policy,\n- crossOriginEmbedderPolicy - Cross-Origin-Embedder-Policy,\n- crossOriginOpenerPolicy - Cross-Origin-Opener-Policy,\n- crossOriginResourcePolicy - Cross-Origin-Resource-Policy,\n- permissionsPolicy - Permissions-Policy,\n- referrerPolicy - Referrer-Policy,\n- strictTransportSecurity - Strict-Transport-Security,\n- xContentTypeOptions - X-Content-Type-Options,\n- xFrameOptions - X-Frame-Options,\n- xPermittedCrossDomainPolicies - X-Permitted-Cross-Domain-Policies\n\nYou should note that `Pragma` has been [deprecated by owasp](https://owasp.org/www-project-secure-headers/#pragma), this plugin will issue a warning when you are still using Pragma and might drop support.\n\n###### Subset of OWASP Secure Headers with user defined values\n\nIf you wish to override the OWASP Secure Headers, you can write your `methodResponse` like:\n\n```yml\nmethodResponse:\n  - statusCode: 200\n    responseBody:\n      description: Success\n    responseModels:\n      application/json: \"CreateResponse\"\n    owasp:\n      cacheControl:\n        value: no-store\n```\n\nThis will set the `Cache-Control` Response Header to have a value of \"no-store\" rather than any value the OWASP Secure Headers Project recommends.\n\n## Validator\n\nValidation for the OpenAPI Description is now (as of 0.0.90) done by [Redocly](https://redocly.com/). This is a slightly less opinionated validator for an OpenAPI Description, it should result in less errors around \"YAML Anchors\". It's also a maintained library, and has support for OpenAPI 3.1.0 which I hope to be able to support very soon.\n\nI am making use of https://www.npmjs.com/package/@redocly/openapi-core, which I have been warned is likely to change. If you notice anything going wrong with validation of your OpenAPI Description, feel free to open an issue here. I make active use of this library, so will hopefully come across those issues too.\n\n### Rules\n\nI have configured the validator to use these Rules:\n\n- [struct](https://redocly.com/docs/cli/rules/oas/struct)\n- [path-parameters-defined](https://redocly.com/docs/cli/rules/oas/path-parameters-defined)\n- [operation-2xx-response](https://redocly.com/docs/cli/rules/oas/operation-2xx-response)\n- [operation-4xx-response](https://redocly.com/docs/cli/rules/oas/operation-4xx-response)\n- [operation-operationId-unique](https://redocly.com/docs/cli/rules/oas/operation-operationId-unique)\n- [path-declaration-must-exist](https://redocly.com/docs/cli/rules/oas/path-declaration-must-exist)\n\nHowever, you can configure your own rules from the [ruleset available on the Redocly site](https://redocly.com/docs/cli/rules/built-in-rules/). To do this, you will need to create a `redocly.json` file within an `options` folder. The file should look like:\n\n```json\n{\n  \"struct\": \"error\",\n  \"path-parameters-defined\": \"error\",\n  \"operation-2xx-response\": \"error\",\n  \"operation-4xx-response\": \"error\",\n  \"operation-operationId-unique\": \"error\",\n  \"path-declaration-must-exist\": \"error\"\n}\n```\n\nSince rules can be set to \"warn\", you no longer are required to tell the plugin to ignore errors with the `--validationWarn` flag.\n\n## Example configuration\n\nPlease view the example [serverless.yml](test/serverless-tests/best/serverless.yml).\n\n## Notes on schemas\n\nSchemas 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).\n\nIf they exist as an external reference, for instance:\n\n```yaml\nschema: https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/bettercodehub.json\n```\n\nWe 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:\n\n```json\n{\n  \"$schema\": \"https://json-schema.org/draft-04/schema\",\n  \"title\": \"Reusable Definitions\",\n  \"type\": \"object\",\n  \"id\": \"https://raw.githubusercontent.com/json-editor/json-editor/master/tests/fixtures/definitions.json\",\n  \"definitions\": {\n    \"address\": {\n      \"title\": \"Address\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"street_address\": { \"type\": \"string\" },\n        \"city\": { \"type\": \"string\" },\n        \"state\": { \"type\": \"string\" }\n      },\n      \"required\": [\"street_address\"]\n    },\n    \"link\": { \"$refs\": \"./properties.json#/properties/title\" }\n  },\n  \"properties\": {\n    \"address\": { \"$refs\": \"#/definitions/address\" }\n  }\n}\n```\n\nWhere 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 Description.\n\nBecause 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.\n\nYou 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:\n\n```js\n\"use strict\";\n\n// options from: https://apitools.dev/json-schema-ref-parser/docs/options.html\n\nmodule.exports = {\n  continueOnError: true, // Don't throw on the first error\n  parse: {\n    json: false, // Disable the JSON parser\n    yaml: {\n      allowEmpty: false, // Don't allow empty YAML files\n    },\n    text: {\n      canParse: [\".txt\", \".html\"], // Parse .txt and .html files as plain text (strings)\n      encoding: \"utf16\", // Use UTF-16 encoding\n    },\n  },\n  resolve: {\n    file: false, // Don't resolve local file references\n    http: {\n      timeout: 2000, // 2 second timeout\n      withCredentials: true, // Include auth credentials when resolving HTTP references\n    },\n  },\n  dereference: {\n    circular: false, // Don't allow circular $refs\n    excludedPathMatcher: (\n      path // Skip dereferencing content under any 'example' key\n    ) =\u003e path.includes(\"/example/\"),\n  },\n};\n```\n\nIf you don't supply this file, it will use the default options.\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredce%2Fserverless-openapi-documenter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaredce%2Fserverless-openapi-documenter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredce%2Fserverless-openapi-documenter/lists"}