Previously, you might have been using Swagger 2.0 (also known as OAS 2), but now, it's time to upgrade to the OpenAPI Specification (OAS) 3. In this article, we will outline the key points of the upgrade process and the essentials of documenting APIs using OAS 3.
Some of these points might still be applicable to the previous OAS 2 (formerly known as Swagger) documents, but it's worth noting as I may not have fully emphasized them before.
The code examples in this article are extracted from the OAS 3 specification of bookmarks.dev-api, which is available in the openapi.yaml file on GitHub. The results can be viewed at bookmarks.dev/api/docs/.
Here are ten key considerations:
1. Read the Specification Document
Read the article "A Guide to What's New in OpenAPI 3.0," which shares some of the major updates in the latest version of OAS and provides detailed insights into what you need to know when transitioning from OAS 2.0 to OAS 3.0. This article is based on the 1-hour webinar "OpenAPI 3.0, And What it Means for the Future of Swagger."
2.Use a Converter Web Service
Use the OpenAPI/Swagger 2.0 to OpenAPI 3.0 converter web service to transform your Swagger specifications into OpenAPI 3.0.
It's available online at https://converter.swagger.io/, and you can also use it as a Docker image:
docker pull swaggerapi/swagger-converter:v1.0.2 docker run -it -p 8080:8080 --name swagger-converter swaggerapi/swagger-converter:v1.0.2
3.Validate Your Specification and Preview with Swagger Editor
Swagger Editor enables you to edit YAML-formatted Swagger API specifications in your web browser and instantly preview the documentation.
You can use it online or as an npm-published version or a Docker image. For more details, refer to the project's README.
4.Showcase Your Documentation with Swagger UI
You can use it directly, like me, by accessing the Swagger UI documentation through an API route, for example, bookmarks.dev/api/docs/. Here's a code snippet from app.js:
const swaggerUi = require('swagger-ui-express'); const YAML = require('yamljs'); const swaggerDocument = YAML.load('./docs/openapi/openapi.yaml'); app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
Including the open specification file (openapi.yaml) in your nodemon watch (e.g., nodemon --inspect ./bin/www --watch src --watch docs/openapi/openapi.yaml) can be helpful, allowing you to reload the UI without manually restarting the ExpressJS server.
4.1. Use swagger-jsdoc for Code-First Approach
Another noteworthy point is that you can use swagger-jsdoc to integrate Swagger through JSDoc annotations in your code. The swagger-jsdoc project assumes that you want to document existing, active, working code in a way that "breathes life" into it, generating a specification that can be fed into other Swagger tools rather than the other way around.
Currently, I manage documentation in a single openapi.yaml file, but I may consider using it in the future.
5.Group Operations Using Tags
You can assign a tag list to each API operation, making it convenient for Swagger UI and Swagger Editor to display operations by tags. To control the sorting in Swagger UI, you need to add them as global tags at the root level. You can also add descriptions and links to external documents there.
Here are the tags I use for the API:
yamlCopy code tags:- name: rootdescription: Used to mark root endpoints- name: versiondescription: Access project version and gitSha1- name: public-bookmarksdescription: Access public bookmarks- name: personal-bookmarksdescription: Operations on personal bookmarks- name: user-datadescription: Operations on user data- name: helperdescription: Helper endpoints/operations
6.Specify API Base URLs with Servers
In OpenAPI 3.0, you use the servers array to specify one or more base URLs for the API. Servers replace the host, basePath, and schemes keywords used in OpenAPI 2.0. Each server has a URL and an optional description in Markdown format.
yamlCopy code servers:- url: http://localhost:3000/apidescription: Local server for development- url: https://www.bookmarks.dev/apidescription: Main (production) server
7.Define and Reuse Resources with Components
Often, several API operations share common parameters or return the same response structure. To avoid code duplication, you can place common definitions in the global components section and reference them using $ref.
For instance, for the response common to several operations where a list of bookmarks appears, I define a BookmarkListResponse under components > responses:
components:responses:BookmarkListResponse:description: List of bookmarkscontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Bookmark"
And then, I reference it in different operations, such as get-public-bookmarks:
yamlCopy code /public/bookmarks:get:summary: Return a list of public bookmarks using query parameters.tags:- public-bookmarksparameters:- $ref: "#/components/parameters/searchTextQueryParam"- $ref: "#/components/parameters/limitQueryParam"- $ref: "#/components/parameters/locationQueryParam"responses:200:description: OK$ref: "#/components/responses/BookmarkListResponse"
Note the locationQueryParam mentioned above. It's defined under components > parameters and referenced in multiple places in the API specification, including the example shown above.
8.Add Examples for Clarity
You can add examples to parameters, properties, and objects to make your Web service's specification clearer. Examples can be read by tools and libraries for your API. For instance, a mock API tool can use example values to generate mock requests. You can specify examples for objects, individual properties, and operation parameters using the example or examples keys.
For instance, you can have complex values as examples for a search text parameter:
components:parameters:searchTextQueryParam:name: qin: querydescription: | Search query (words separated by spaces). Special filters available: * `lang:iso_language_code` - e.g., `lang:en` for English, `lang:es` for Spanish, `lang:de` for German bookmarks * `site:site_URL` - e.g., return bookmarks from [www.codepedia.org](htt