<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kate Bartolo</title>
    <description>The latest articles on Forem by Kate Bartolo (@kabartolo).</description>
    <link>https://forem.com/kabartolo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F520265%2F7a9ce941-cc98-4e89-b53a-91d2e903e205.jpeg</url>
      <title>Forem: Kate Bartolo</title>
      <link>https://forem.com/kabartolo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kabartolo"/>
    <language>en</language>
    <item>
      <title>How to Document an Express API with Swagger UI and JSDoc</title>
      <dc:creator>Kate Bartolo</dc:creator>
      <pubDate>Sun, 29 Nov 2020 19:01:33 +0000</pubDate>
      <link>https://forem.com/kabartolo/how-to-document-an-express-api-with-swagger-ui-and-jsdoc-50do</link>
      <guid>https://forem.com/kabartolo/how-to-document-an-express-api-with-swagger-ui-and-jsdoc-50do</guid>
      <description>&lt;p&gt;&lt;a href="https://jsdoc.app/" rel="noopener noreferrer"&gt;JSDoc&lt;/a&gt; is a popular tool for generating documentation from comments in the source code of your app. This serves two purposes. First, the documentation is directly available to anyone viewing the source code. Second, the comments can be compiled later into a complete set of reference documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://swagger.io" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt; provides a tool for presenting this documentation: &lt;a href="https://swagger.io/tools/swagger-ui/" rel="noopener noreferrer"&gt;Swagger UI&lt;/a&gt;. Swagger UI creates a web page from &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" rel="noopener noreferrer"&gt;OpenAPI Specification&lt;/a&gt; definitions. As this tutorial will show, these definitions can be written in YAML directly in JSDoc comments.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will set up a &lt;a href="https://swagger.io/tools/swagger-ui/" rel="noopener noreferrer"&gt;Swagger UI&lt;/a&gt; documentation web page for an Express API. You can then write JSDoc comments in your API's source code to generate the OpenAPI definitions. By the end, you will have documentation that follows the OpenAPI Specification, presented from a custom &lt;code&gt;/docs&lt;/code&gt; endpoint added to your Express API:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjuc1ws15olef5vm7peih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjuc1ws15olef5vm7peih.png" alt="Swagger UI Docs Page" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To complete this tutorial, you'll need&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Familiarity with REST APIs and &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.dev/learn/how-to-install-nodejs" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed on your system&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An &lt;strong&gt;Express-based REST API&lt;/strong&gt; running on a local Express server. If you don't have one, you can install the &lt;a href="https://github.com/kabartolo/jsonplaceholder-express-api" rel="noopener noreferrer"&gt;Express API&lt;/a&gt; used in this tutorial. It retrieves user data from &lt;a href="https://jsonplaceholder.typicode.com/" rel="noopener noreferrer"&gt;JSONPlaceholder&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To install and run the sample Express API, first clone the repository (replace &lt;code&gt;test-api&lt;/code&gt; with the directory name of your choosing):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git clone https://github.com/kabartolo/jsonplaceholder-express-api test-api


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, run the following commands to start the Express server (replace &lt;code&gt;test-api&lt;/code&gt; with the name of the directory you just created):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;cd &lt;/span&gt;test-api
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run start


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Navigate&lt;/strong&gt; to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000&lt;/code&gt;&lt;/a&gt; to see the API. You should see links to &lt;code&gt;/users&lt;/code&gt; and &lt;code&gt;/users/1&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnlqr49528h817w6wd4iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnlqr49528h817w6wd4iv.png" alt="API Homepage" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to either of these to see user data from JSONPlaceholder.&lt;/p&gt;

&lt;p&gt;The code added during this tutorial can be found in the repository's &lt;a href="https://github.com/kabartolo/jsonplaceholder-express-api/tree/docs" rel="noopener noreferrer"&gt;&lt;code&gt;docs&lt;/code&gt; branch&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terminology
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;OpenAPI&lt;/em&gt; is the name of the specification, while &lt;em&gt;Swagger&lt;/em&gt; is the set of tools that implement this specification. See &lt;a href="https://swagger.io/blog/api-strategy/difference-between-swagger-and-openapi/" rel="noopener noreferrer"&gt;What Is the Difference Between Swagger and OpenAPI?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tutorial uses the following API-related terms and definitions defined by &lt;a href="https://swagger.io/docs/specification/api-host-and-base-path/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    https://api.example.com/v1/users?role=admin&amp;amp;status=active
    \________________________/\____/ \______________________/
             server URL       endpoint    query parameters
                                path


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server URL or base URL&lt;/strong&gt;: The base URL for all API endpoints: &lt;code&gt;localhost:3000&lt;/code&gt; or &lt;code&gt;example.com/api&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint path&lt;/strong&gt;: The path representing the location of the resource (relative to the base URL): &lt;code&gt;/users&lt;/code&gt; or &lt;code&gt;/users/1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operation&lt;/strong&gt;: The HTTP method used to manipulate endpoint paths: GET, POST, PUT, DELETE&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource&lt;/strong&gt;: Information representing a real-world object (e.g., a user or book), usually returned by the API as JSON data. Represented by a database &lt;strong&gt;model&lt;/strong&gt; in Express.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full URL used to retrieve data from the API is formed by adding the endpoint to the base URL: &lt;code&gt;localhost:3000/users&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set up the application
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1: Install &lt;code&gt;swagger-jsdoc&lt;/code&gt; and &lt;code&gt;swagger-ui-express&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To create a Swagger UI page from JSDoc comments, you’ll need a way to pass your documentation to Swagger UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://github.com/Surnet/swagger-jsdoc" rel="noopener noreferrer"&gt;&lt;code&gt;swagger-jsdoc&lt;/code&gt;&lt;/a&gt;  generates OpenAPI definitions from JSDoc comments.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/scottie1984/swagger-ui-express" rel="noopener noreferrer"&gt;&lt;code&gt;swagger-ui-express&lt;/code&gt;&lt;/a&gt; creates the Swagger UI page from these definitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To install &lt;code&gt;swagger-jsdoc&lt;/code&gt; and &lt;code&gt;swagger-ui-express&lt;/code&gt; to your Express API, run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm &lt;span class="nb"&gt;install &lt;/span&gt;swagger-jsdoc@5.0.1 &lt;span class="nt"&gt;--save-exact&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;swagger-ui-express &lt;span class="nt"&gt;--save&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;This tutorial uses &lt;code&gt;swagger-jsdoc&lt;/code&gt; version &lt;code&gt;5.0.1&lt;/code&gt;. The latest version might not be compatible with this tutorial. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1.2: Create an API specification
&lt;/h3&gt;

&lt;p&gt;Swagger UI creates a docs page from a set of OpenAPI definitions. These definitions are written in &lt;a href="https://yaml.org/" rel="noopener noreferrer"&gt;YAML&lt;/a&gt; or &lt;a href="https://json.org" rel="noopener noreferrer"&gt;JSON&lt;/a&gt; to describe a REST API. For more information on the basic structure of the OpenAPI Specification, see &lt;a href="https://swagger.io/docs/specification/basic-structure/" rel="noopener noreferrer"&gt;Basic Structure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In your Express API's &lt;code&gt;app.js&lt;/code&gt; file, add the following code below the list of required modules:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerJSDoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swagger-jsdoc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerDefinition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;openapi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Express API for JSONPlaceholder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;swaggerDefinition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Paths to files containing OpenAPI definitions&lt;/span&gt;
  &lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes/*.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerSpec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;swaggerJSDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;swaggerDefinition&lt;/code&gt; object (i.e., the OpenAPI definition) defines the root information for your API. Provide a few basic pieces of information to the &lt;code&gt;swaggerDefinition&lt;/code&gt;, such as the &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt; of your API; you can fill in more later.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;options&lt;/code&gt; object contains this &lt;code&gt;swaggerDefinition&lt;/code&gt; object and an array of paths called &lt;code&gt;apis&lt;/code&gt;. These are paths to files containing other OpenAPI definitions. These file paths should be relative to the root directory of your Express API. In our case, definitions will be written in JSDoc directly in the &lt;code&gt;/routes&lt;/code&gt; files. You can list the filenames individually or use the wildcard delimiter &lt;code&gt;*&lt;/code&gt; to add all JavaScript files in a directory, as shown above.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;options&lt;/code&gt; object is used by &lt;code&gt;swagger-jsdoc&lt;/code&gt; to produce an OpenAPI specification in a variable called &lt;code&gt;swaggerSpec&lt;/code&gt;. This specification is equivalent to the &lt;code&gt;swagger.json&lt;/code&gt; or &lt;code&gt;swagger.yaml&lt;/code&gt; file normally used by Swagger UI to create a docs page. You'll pass this object to Swagger UI in the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server to ensure there are no errors. If you get any errors at this stage, check that your &lt;code&gt;swagger-jsdoc&lt;/code&gt; version is &lt;code&gt;5.0.1&lt;/code&gt; exactly.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3: Create the Swagger UI docs page
&lt;/h3&gt;

&lt;p&gt;To create a Swagger UI page for your Express API, include &lt;code&gt;swagger-ui-express&lt;/code&gt; in the &lt;code&gt;app.js&lt;/code&gt; file. Then, add an endpoint path called &lt;code&gt;/docs&lt;/code&gt; (or any name of your choosing):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerJSDoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swagger-jsdoc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerUi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swagger-ui-express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/docs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;swaggerUi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;swaggerUi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;swaggerSpec&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As shown above, &lt;code&gt;swagger-ui-express&lt;/code&gt; provides two callbacks to set up the endpoint: one to &lt;strong&gt;set up&lt;/strong&gt; Swagger UI with the &lt;code&gt;swaggerSpec&lt;/code&gt; definitions and one to &lt;strong&gt;serve&lt;/strong&gt; it to the &lt;code&gt;/docs&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser.&lt;/p&gt;

&lt;p&gt;You'll see the title and version number of your Express API, as well as the OpenAPI version number (&lt;code&gt;3.0.0&lt;/code&gt;). Since we have no other definitions yet, you'll see a "No operations defined in spec!" message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffvsnzhvcj94o3ced81lk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffvsnzhvcj94o3ced81lk.png" alt="Basic Swagger UI Page" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You now have the start of a beautiful docs page for your API! The rest of this tutorial provides a basic introduction to OpenAPI definitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define your API's root information
&lt;/h2&gt;

&lt;p&gt;You've created a Swagger UI docs page, and you're set to start writing docs. But first, you should add more root definitions for the API.&lt;/p&gt;

&lt;p&gt;Return to &lt;code&gt;app.js&lt;/code&gt;. Note that the &lt;code&gt;info&lt;/code&gt; object maps to OpenAPI's &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#infoObject" rel="noopener noreferrer"&gt;Info Object&lt;/a&gt; to define a title, description, list of servers, contact information, and list of paths for your API.&lt;/p&gt;

&lt;p&gt;Here is an example of a more complete definition:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swaggerDefinition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;openapi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Express API for JSONPlaceholder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a REST API application made with Express. It retrieves data from JSONPlaceholder.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Licensed Under MIT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://spdx.org/licenses/MIT.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JSONPlaceholder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Development server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you have a production server, add the URL and a description to the &lt;code&gt;servers&lt;/code&gt; list. See &lt;a href="https://swagger.io/docs/specification/basic-structure/" rel="noopener noreferrer"&gt;Basic Structure&lt;/a&gt; for more information on the other properties you can add to the root definition.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://swagger.io/docs/specification/basic-structure/" rel="noopener noreferrer"&gt;OpenAPI docs&lt;/a&gt;, you'll notice there's also a &lt;code&gt;paths&lt;/code&gt; field. You won't need to specify the path definitions here, since each path is defined separately in a JSDoc comment (to be added in the next step). These path definitions are compiled by &lt;code&gt;swagger-jsdoc&lt;/code&gt; into a &lt;code&gt;paths&lt;/code&gt; object for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You should see more information about your API at the top of the docs page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9lw2xrss7nz5f0fq1t5i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9lw2xrss7nz5f0fq1t5i.png" alt="Swagger UI Page with API Information" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now start documenting your Express routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Write the docs
&lt;/h2&gt;

&lt;p&gt;With a Swagger UI docs page available at the &lt;code&gt;/docs&lt;/code&gt; endpoint and a complete set of root information on your API, you can start writing your path definitions. Each path definition corresponds to an Express route in your API. It describes both the operation and endpoint path, such as &lt;code&gt;GET /users&lt;/code&gt; and &lt;code&gt;DELETE /users/:id&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1: Document the routes
&lt;/h3&gt;

&lt;p&gt;To document &lt;code&gt;/routes/users.js&lt;/code&gt;, first add a comment starting with &lt;code&gt;@swagger&lt;/code&gt; above the first route. Follow this with some basic information about the route:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users:
 *   get:
 *     summary: Retrieve a list of JSONPlaceholder users
 *     description: Retrieve a list of users from JSONPlaceholder. Can be used to populate a list of fake users when prototyping or testing an API.
*/&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note that &lt;code&gt;swagger-jsdoc&lt;/code&gt; looks for comments with a &lt;code&gt;@swagger&lt;/code&gt; or &lt;code&gt;@openapi&lt;/code&gt; tag to create OpenAPI definitions.&lt;/p&gt;

&lt;p&gt;As shown in the code example, add the endpoint path &lt;code&gt;/users&lt;/code&gt; and the operation &lt;code&gt;get&lt;/code&gt; (indented two spaces). The path in the Express router function &lt;code&gt;get('/')&lt;/code&gt; is relative to &lt;code&gt;/users&lt;/code&gt;, so the path in the definition should be &lt;code&gt;/users&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;summary&lt;/code&gt; should be a brief description of the goal of this route. The &lt;code&gt;description&lt;/code&gt; should provide more detail, such as when or why you would want to use the route.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be sure to use two spaces (or four spaces) for indentation, not tabs. Refer to &lt;a href="https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html" rel="noopener noreferrer"&gt;YAML Syntax&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You should see a listing for &lt;code&gt;GET /users&lt;/code&gt; near the bottom of the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F76tz1fkiserr8dnwe02c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F76tz1fkiserr8dnwe02c.png" alt="Swagger UI Page Showing First Path" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2: Document responses
&lt;/h3&gt;

&lt;p&gt;Your users will want to know what is returned when this GET request is successful (i.e., with a status code of &lt;code&gt;200&lt;/code&gt;).  To define a successful response, add a &lt;code&gt;responses&lt;/code&gt; object and a response called &lt;code&gt;200&lt;/code&gt; to the path definition:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users:
 *   get:
 *     summary: Retrieve a list of JSONPlaceholder users.
 *     description: Retrieve a list of users from JSONPlaceholder. Can be used to populate a list of fake users when prototyping or testing an API.
 *     responses:
 *       200:
 *         description: A list of users.
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: integer
 *                         description: The user ID.
 *                         example: 0
 *                       name:
 *                         type: string
 *                         description: The user's name.
 *                         example: Leanne Graham
 */&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;description&lt;/code&gt; field describes the response or what it returns. The &lt;code&gt;content&lt;/code&gt; field describes the content type (&lt;code&gt;application/json&lt;/code&gt;), and the &lt;code&gt;schema&lt;/code&gt; describes the response object. In our case, JSONPlaceholder returns an object with a &lt;code&gt;data&lt;/code&gt; field, which contains the data you've requested. For this response, &lt;code&gt;data&lt;/code&gt; contains an array of user objects. Add just one or two user properties (e.g., &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt;) to avoid cluttering the file for now. &lt;/p&gt;

&lt;p&gt;Add a real example value for each property (e.g., &lt;code&gt;'Leanne Graham'&lt;/code&gt;); otherwise, Swagger UI creates a generic example such as &lt;code&gt;'string'&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Notice how the types are defined in this schema. For example, to define an array, add &lt;code&gt;type: array&lt;/code&gt; and an &lt;code&gt;items&lt;/code&gt; field. Read more about types in the &lt;a href="https://swagger.io/docs/specification/data-models/data-types/" rel="noopener noreferrer"&gt;Data Types&lt;/a&gt; documentation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can also describe &lt;strong&gt;error&lt;/strong&gt; responses this way. See Swagger's &lt;a href="https://swagger.io/docs/specification/describing-responses/" rel="noopener noreferrer"&gt;Describing Responses&lt;/a&gt; documentation for more details on the fields available for describing each response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You should see the response, an example value (using the example values you provided for each property), and the schema for the data returned in this response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpyqmavht837zspni1mrx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpyqmavht837zspni1mrx.png" alt="Response and Schema" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, define the &lt;code&gt;GET /users/:id&lt;/code&gt; path by adding the fields we've covered already (&lt;code&gt;summary&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;responses&lt;/code&gt;):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

 &lt;span class="cm"&gt;/**
 * @swagger
 * /users/{id}:
 *   get:
 *     summary: Retrieve a single JSONPlaceholder user.
 *     description: Retrieve a single JSONPlaceholder user. Can be used to populate a user profile when prototyping or testing an API.
 *     responses:
 *       200:
 *         description: A single user.
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: integer
 *                       description: The user ID.
 *                       example: 0
 *                     name:
 *                       type: string
 *                       description: The user's name.
 *                       example: Leanne Graham
*/&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, the path parameter (&lt;code&gt;id&lt;/code&gt;) is added to the endpoint path: &lt;code&gt;/users/{id}&lt;/code&gt;. Curly brackets (&lt;code&gt;{}&lt;/code&gt;) are used to mark a path parameter in the endpoint path. Note that the colon style (&lt;code&gt;/users/:id&lt;/code&gt;) won't work with Swagger (thanks &lt;a class="mentioned-user" href="https://dev.to/sherwinwater"&gt;@sherwinwater&lt;/a&gt; for pointing this out!).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;data&lt;/code&gt; object in this &lt;code&gt;schema&lt;/code&gt; contains a single user object instead of an array of user objects, but the properties are the same. &lt;/p&gt;

&lt;p&gt;Next, define &lt;code&gt;POST /users&lt;/code&gt; by adding the fields we've covered already (&lt;code&gt;summary&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;responses&lt;/code&gt;):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users:
 *   post:
 *     summary: Create a JSONPlaceholder user.
 *     responses:
 *       201:
 *         description: Created
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: integer
 *                       description: The user ID.
 *                       example: 0
 *                     name:
 *                       type: string
 *                       description: The user's name.
 *                       example: Leanne Graham
*/&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A successful response in this case would be &lt;code&gt;201&lt;/code&gt;. It returns an object with a &lt;code&gt;data&lt;/code&gt; field containing the new user. &lt;/p&gt;

&lt;p&gt;You can continue adding path definitions for the remaining routes in the same way. We'll do some refactoring in a later step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You'll now see a listing for &lt;code&gt;GET /users/{id}&lt;/code&gt;, &lt;code&gt;POST /users&lt;/code&gt;, and any other path definitions you've added:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjuc1ws15olef5vm7peih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjuc1ws15olef5vm7peih.png" alt="Swagger UI Docs Page" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3: Document the requests
&lt;/h3&gt;

&lt;p&gt;Request data such as parameters and request bodies can also be documented in your OpenAPI definitions. For example, &lt;code&gt;GET /users/:id&lt;/code&gt; has an &lt;code&gt;id&lt;/code&gt; parameter, which should be documented.&lt;/p&gt;

&lt;p&gt;To document parameters, add a &lt;code&gt;parameters&lt;/code&gt; field to the path definition:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users/{id}:
 *   get:
 *     summary: Retrieve a single JSONPlaceholder user.
 *     description: Retrieve a single JSONPlaceholder user. Can be used to populate a user profile when prototyping or testing an API.
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         description: Numeric ID of the user to retrieve.
 *         schema:
 *           type: integer
 *     responses:
 *       200:
 *         ...
 */&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the definition for this parameter, &lt;code&gt;in&lt;/code&gt; defines the parameter's location (in this case, it's a path parameter because it's part of the path). You can also add a &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;schema&lt;/code&gt; and whether the parameter is &lt;code&gt;required&lt;/code&gt;. See &lt;a href="https://swagger.io/docs/specification/describing-parameters/" rel="noopener noreferrer"&gt;Describing Parameters&lt;/a&gt; for more details. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You'll see a list of parameters for this route:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj9keumw9pxe95tzq2kpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj9keumw9pxe95tzq2kpo.png" alt="Route Parameters" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, document the &lt;strong&gt;request body&lt;/strong&gt; for &lt;code&gt;POST /users&lt;/code&gt; to describe the data required to create a new user in the database. To do this, &lt;strong&gt;add&lt;/strong&gt; a &lt;code&gt;requestBody&lt;/code&gt; field to this path definition:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users:
 *   post:
 *     summary: Create a JSONPlaceholder user.
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 type: string
 *                 description: The user's name.
 *                 example: Leanne Graham
 *     responses:
 *       201:
 *         ...
*/&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This adds a request body schema to this path definition. This example shows that &lt;code&gt;name&lt;/code&gt; can be sent in the request body. You can add more properties for new users later. See &lt;a href="https://swagger.io/docs/specification/describing-request-body/" rel="noopener noreferrer"&gt;Describing Request Body&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You'll see a section called &lt;code&gt;Request body&lt;/code&gt; with the schema you've provided:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5b7ktwvrhuqlcugl7q14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5b7ktwvrhuqlcugl7q14.png" alt="Request Body" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4: Document the resources
&lt;/h3&gt;

&lt;p&gt;You might have noticed you've repeated the user schema several times in the documentation so far. To avoid this duplication, you can define the user schema in one place and reference it from elsewhere.&lt;/p&gt;

&lt;p&gt;Each model defined by your Express API can be documented separately as a schema definition (or &lt;a href="https://swagger.io/docs/specification/components/" rel="noopener noreferrer"&gt;component&lt;/a&gt;). To do this for the user model, add a &lt;code&gt;User&lt;/code&gt; schema definition to the top of the file, under &lt;code&gt;components/schemas&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * components:
 *   schemas:
 *     User:
 *       type: object
 *       properties:
 *         id:
 *           type: integer
 *           description: The user ID.
 *           example: 0
 *         name:
 *           type: string
 *           description: The user's name.
 *           example: Leanne Graham
 */&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can then reference this schema definition using &lt;code&gt;$ref&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// routes/users.js&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users:
 *   get:
 *     summary: Retrieve a list of JSONPlaceholder users
 *     description: Retrieve a list of users from JSONPlaceholder. Can be used to populate a list of fake users when prototyping or testing an API.
 *     responses:
 *       200:
 *         description: A list of users.
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items:
 *                 $ref: '#/components/schemas/User'
 */&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;$ref&lt;/code&gt; path uses &lt;a href="https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03" rel="noopener noreferrer"&gt;JSON Reference&lt;/a&gt; notation. The &lt;code&gt;#&lt;/code&gt; symbol indicates the root of the current document, and the remaining nested values are then resolved in order. For more information, see &lt;a href="https://swagger.io/docs/specification/using-ref/" rel="noopener noreferrer"&gt;Using $ref&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. Your path definitions will now use this &lt;code&gt;User&lt;/code&gt; schema, and you should see a schema definition for &lt;code&gt;User&lt;/code&gt; at the bottom of the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7cdcc3ad8wzz57aufx97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7cdcc3ad8wzz57aufx97.png" alt="User Schema" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, you can define a &lt;code&gt;NewUser&lt;/code&gt; object to reference in the &lt;code&gt;POST /users&lt;/code&gt; request body. Since it contains some but not all of the fields from the &lt;code&gt;User&lt;/code&gt; schema, you can also use &lt;code&gt;$ref&lt;/code&gt; to avoid duplication between them:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * components:
 *   schemas:
 *     NewUser:
 *       type: object
 *       properties:
 *         name:
 *           type: string
 *           description: The user's name.
 *           example: Leanne Graham
 *     User:
 *       allOf:
 *         - type: object
 *           properties:
 *             id:
 *               type: integer
 *               description: The user ID.
 *               example: 0
 *         - $ref: '#/components/schemas/NewUser'
 */&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;allOf&lt;/code&gt; keyword combines model definitions, in this case the &lt;code&gt;NewUser&lt;/code&gt; definition (containing the &lt;code&gt;name&lt;/code&gt; property) and an object with an &lt;code&gt;id&lt;/code&gt; property. See &lt;a href="https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/" rel="noopener noreferrer"&gt;oneOf, anyOf, allOf, not&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;You can now reference &lt;code&gt;NewUser&lt;/code&gt; from the request body definition for &lt;code&gt;POST /users&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/**
 * @swagger
 * /users:
 *   post:
 *     summary: Create a JSONPlaceholder user.
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/NewUser'
 *     responses:
 *       201:
 *         ...
*/&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Restart&lt;/strong&gt; the Express server, and &lt;strong&gt;navigate&lt;/strong&gt; again to &lt;a href="http://localhost:3000/docs" rel="noopener noreferrer"&gt;&lt;code&gt;localhost:3000/docs&lt;/code&gt;&lt;/a&gt; in the browser. You'll see your &lt;code&gt;NewUser&lt;/code&gt; schema in the request body definition for &lt;code&gt;POST /users&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fglkw439i08pi4bk00bak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fglkw439i08pi4bk00bak.png" alt="NewUser Schema" width="800" height="362"&gt;&lt;/a&gt;&lt;br&gt;
This covers the basic techniques for producing OpenAPI definitions in JSDoc comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You are now set up to produce a complete reference documentation page for your Express API. You've created a basic set of OpenAPI definitions and a Swagger UI page that displays them. If you want more practice with the OpenAPI Specification, you can finish documenting the &lt;code&gt;jsonplaceholder-express-api&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This tutorial has also covered the basics of writing OpenAPI definitions. To complete your documentation, consult the &lt;a href="https://swagger.io/specification/" rel="noopener noreferrer"&gt;OpenAPI Specification&lt;/a&gt; and the &lt;a href="https://swagger.io/docs/specification/about/" rel="noopener noreferrer"&gt;Swagger Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To see a version of the &lt;code&gt;jsonplaceholder-express-api&lt;/code&gt; that includes all the code added during this tutorial, see the repository's &lt;a href="https://github.com/kabartolo/jsonplaceholder-express-api/tree/docs" rel="noopener noreferrer"&gt;&lt;code&gt;docs&lt;/code&gt; branch&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>api</category>
      <category>documentation</category>
    </item>
  </channel>
</rss>
