{"id":24092,"date":"2022-12-09T10:30:34","date_gmt":"2022-12-09T15:30:34","guid":{"rendered":"https:\/\/blog.logrocket.com\/?p=24092"},"modified":"2024-06-04T17:02:19","modified_gmt":"2024-06-04T21:02:19","slug":"documenting-express-js-api-swagger","status":"publish","type":"post","link":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/","title":{"rendered":"Documenting your Express API with Swagger"},"content":{"rendered":"<!DOCTYPE html>\n<html><p><em><strong>Editor\u2019s note:<\/strong> This post on documenting an Express.js API with Swagger was last updated on 9 December 2022 to add sections on how to connect Swagger to Node.js, the benefits of Swagger, and how to use CSS to customize Swagger. This update also addresses errors in the code present in the previous version.&nbsp;<\/em><\/p><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"487\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png\" class=\"attachment-full size-full wp-post-image\" alt=\"Documenting Express.js API With Swagger\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger-300x200.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\">\n<p>We all know about the importance of documenting your APIs. In terms of Node.js APIs, whether they were built on top of Express.js or any other framework, you\u2019ve got plenty of open source options. These include apiDoc, docbox, and others.<\/p>\n<p>In this tutorial, we will explore using Swagger with an Express.js API. Swagger is an open source set of tools that enable you to design, build, document, and use <a href=\"https:\/\/blog.logrocket.com\/crud-rest-api-node-js-express-postgresql\/\">RESTful web services<\/a>. It was created to be mostly <a href=\"https:\/\/github.com\/swagger-api\/swagger-codegen#overview\">agnostic<\/a>, meaning you can use it with pretty much any of your favorite languages and frameworks.<\/p>\n<p>In our example, we\u2019ll use two libraries: swagger-ui-express and swagger-jsdoc. The first is a module that allows you to feed a Swagger UI (auto-generated views based on the swagger-ui project) from a <code>swagger.json<\/code> file or an inline object.<\/p>\n<p>The second project is about integrating Swagger using JSDoc comments throughout your code. This is useful, especially when you have extensive APIs and dozens of models.<\/p>\n<p><em>Jump ahead:<\/em><\/p>\n<ul>\n<li><a href=\"#benefits-using-swagger\"> Benefits of using Swagger<\/a><\/li>\n<li><a href=\"#express-js-api-application-setup\"> Express.js API application setup<\/a><\/li>\n<li><a href=\"#connect-swagger-node-js\"> How to connect Swagger to Node.js<\/a><\/li>\n<li><a href=\"#creating-api-model\"> Creating the API model<\/a>\n<ul style=\"margin-bottom: 0px; padding-bottom: 0px;\">\n<li><a href=\"#integrating-operations-into-routes\"> Integrating operations into the routes<\/a><\/li>\n<li><a href=\"#mapping-endpoints\"> Mapping the endpoints<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#swagger-customization-css\"> Swagger customization with CSS<\/a><\/li>\n<\/ul>\n<h2 id=\"benefits-using-swagger\">Benefits of using Swagger<\/h2>\n<p>Before we get into the Swagger integration into your Node.js application, let\u2019s examine why Swagger is important for any application \u2014 how it helps in the development process.<\/p>\n<p>One significant benefit of Swagger is that it helps to understand how API works for the client side of an application. Swagger synchronizes the API between the client and server side of the application. That way, developers who work in frontend can understand how the API works and integrate the APIs into the client side.<\/p>\n<p>Another benefit of using Swagger is that it\u2019s comprehensive for developers and non-developers. Everyone involved in product development, including <a href=\"https:\/\/blog.logrocket.com\/product-management\/\">product managers<\/a>, stakeholders, and developers, can try out API in UI without needing to run the server independently.<\/p>\n<p>We can customize the API documentation however we like. So, in summary, Swagger\u2019s main advantage is that it makes the API development process faster and more efficient.<\/p>\n<p>Now, we know the advantages of having Swagger in an application, let\u2019s look into setting it up and configuring it in an application.<\/p>\n<h2 id=\"express-js-api-application-setup\">Express.js API application setup<\/h2>\n<p>This tutorial won\u2019t cover anything related to <a href=\"https:\/\/blog.logrocket.com\/build-rest-api-node-express-mysql\/\">Express API building<\/a>. We already have a <a href=\"https:\/\/github.com\/diogosouza\/simple-express-crud-api\">ready-to-use example<\/a> that you can clone to your local machine before implementing.<\/p>\n<p>It\u2019s a simple API that allows you to manage an in-memory list of books. Feel free to increment it with your customizations.<\/p>\n<p>Once you have this in your app, run the commands below in the terminal:<\/p>\n<pre class=\"language-bash hljs\">npm install\nnpm i swagger-ui-express swagger-jsdoc\n<\/pre>\n<p>These are going to download the required dependencies into your application. Now it\u2019s time to integrate Swagger into your Node.js application.<\/p>\n<h2 id=\"connect-swagger-node-js\">How to connect Swagger to Node.js<\/h2>\n<p>To connect Swagger to your Node.js application, import <code>swagger-ui-express<\/code> and <code>swagger-jsdoc<\/code> in <code>server.js<\/code>:<\/p>\n<pre class=\"language-javascript hljs\">const express = require(\"express\"),\n  bodyParser = require(\"body-parser\"),\n  swaggerJsdoc = require(\"swagger-jsdoc\"),\n  swaggerUi = require(\"swagger-ui-express\");\n<\/pre>\n<p>Those are the two respective objects representing the libraries we\u2019ve imported. Next, add the following code before the app\u2019s <code>listen<\/code> function:<\/p>\n<pre class=\"language-javascript hljs\">const options = {\n  definition: {\n    openapi: \"3.1.0\",\n    info: {\n      title: \"LogRocket Express API with Swagger\",\n      version: \"0.1.0\",\n      description:\n        \"This is a simple CRUD API application made with Express and documented with Swagger\",\n      license: {\n        name: \"MIT\",\n        url: \"https:\/\/spdx.org\/licenses\/MIT.html\",\n      },\n      contact: {\n        name: \"LogRocket\",\n        url: \"https:\/\/logrocket.com\",\n        email: \"info@email.com\",\n      },\n    },\n    servers: [\n      {\n        url: \"http:\/\/localhost:3000\",\n      },\n    ],\n  },\n  apis: [\".\/routes\/*.js\"],\n};\n\nconst specs = swaggerJsdoc(options);\napp.use(\n  \"\/api-docs\",\n  swaggerUi.serve,\n  swaggerUi.setup(specs)\n);\n<\/pre>\n<p>As you see in the first line, this configuration object sets an <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/releases\/tag\/3.1.0\"><code>OpenAPI<\/code><\/a> to v3.1.0.<\/p>\n<p>Swagger uses the Open API Specification, a standard, language-agnostic interface for RESTful APIs that allows humans and machines to understand the capabilities of a web service without having to access the source code or inspect the network traffic.<\/p>\n<p>You can refer to the official docs for all available settings for each version. Here, we\u2019re using just the basics: API info, name, title, description, license, the contact of the API owner, and more.<\/p>\n<p>The API\u2019s property is essential because it searches for the model and endpoint definitions, so inform it correctly.<\/p>\n<p>Finally, we\u2019re using the <code>swaggerJsdoc<\/code> function to scan through the options passed in as a param and return the converted Swagger specification object. This one, in turn, can be used along with the <code>swaggerUi<\/code> setup process.<\/p>\n<p>You can now start the application via the <code>npm start<\/code> command. You\u2019ll see the following screen when accessing the <code>http:\/\/localhost:3000\/api-docs\/<\/code> URL:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152170\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-document-swagger.png\" alt=\"Express.js Documenting With Swagger\" width=\"730\" height=\"600\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-document-swagger.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-document-swagger-300x247.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<p>Note, that we still don\u2019t have any operations defined in the spec. This happens because we need to map those operations to the routes explicitly. Otherwise, Swagger can\u2019t figure out the API endpoints on its own.<\/p>\n<p>Optionally, you can add a search bar to your UI just in case your API has too many operations. For this, change the implementation to the following:<\/p>\n<pre class=\"language-javascript hljs\">app.use(\n  \"\/api-docs\",\n  swaggerUi.serve,\n  swaggerUi.setup(specs, { explorer: true })\n);\n<\/pre>\n<p>Now, the search bar will show up:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152172\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-search-bar.png\" alt=\"Express.js and Swagger Example with Search Bar\" width=\"730\" height=\"600\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-search-bar.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-search-bar-300x247.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<h2 id=\"creating-api-model\">Creating the API model<\/h2>\n<p>Like many significant frameworks and API architectures, data is encapsulated into models to become more easily accessible. Swagger also expects your APIs to have models and for you to define them.<\/p>\n<p>Go to <code>routes\/books.js<\/code> and place the following code at the beginning of the file:<\/p>\n<pre class=\"language-javascript hljs\">\/**\n * @swagger\n * components:\n *   schemas:\n *     Book:\n *       type: object\n *       required:\n *         - title\n *         - author\n *         - finished\n *       properties:\n *         id:\n *           type: string\n *           description: The auto-generated id of the book\n *         title:\n *           type: string\n *           description: The title of your book\n *         author:\n *           type: string\n *           description: The book author\n *         finished:\n *           type: boolean\n *           description: Whether you have finished reading the book\n *         createdAt:\n *           type: string\n *           format: date\n *           description: The date the book was added\n *       example:\n *         id: d5fE_asz\n *         title: The New Turing Omnibus\n *         author: Alexander K. Dewdney\n *         finished: false\n *         createdAt: 2020-03-10T04:05:06.157Z\n *\/\n<\/pre>\n<p>Remember the JSDocs we\u2019ve talked about? JSDocs now enters the scene and helps us to set up the rest of the Swagger spec definitions through the <code>@swagger<\/code> annotation. Here, you can define as many schemas as you want. In our case, we\u2019re just defining the domain <code>Books<\/code>.<\/p>\n<p>The required property receives the list of attributes that must be filled in the requests. This step is essential for letting people know what they must send when using your API.<\/p>\n<p>The <code>properties<\/code> property describes detailed information about your model attributes. Each attribute must have a name followed by its type, description (optional), and format (you can validate values too). Please refer to <a href=\"https:\/\/swagger.io\/docs\/specification\/data-models\/data-types\/\">Swagger data types<\/a> for a complete list of available data types.<\/p>\n<p>Finally, you can provide an example of request data for this schema model. That\u2019s going to be useful later. When you restart the app and refresh the page, you\u2019ll see the screen below:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152175\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-documenting-swagger.png\" alt=\"Express.js Documenting with Swagger Book Schema\" width=\"730\" height=\"570\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-documenting-swagger.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-documenting-swagger-300x234.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<p>Much better, isn\u2019t it?<\/p>\n<p>It\u2019s important to note that if you\u2019re facing a <code>YAMLSemanticError<\/code> in the schema, make sure to check the indentation in the YAML configuration:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152177\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-yaml.png\" alt=\"Express.js and Swagger YAML Error\" width=\"730\" height=\"218\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-yaml.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-yaml-300x90.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<h3 id=\"integrating-operations-into-routes\">Integrating operations into the routes<\/h3>\n<p>Now, we have Swagger <code>schema<\/code> integrated into the routes. However, we still don\u2019t have any operations. Let\u2019s fix that. Right after the previous JSDoc comment, add the following:<\/p>\n<pre class=\"language-javascript hljs\">\/**\n * @swagger\n * tags:\n *   name: Books\n *   description: The books managing API\n * \/books:\n *   post:\n *     summary: Create a new book\n *     tags: [Books]\n *     requestBody:\n *       required: true\n *       content:\n *         application\/json:\n *           schema:\n *             $ref: '#\/components\/schemas\/Book'\n *     responses:\n *       200:\n *         description: The created book.\n *         content:\n *           application\/json:\n *             schema:\n *               $ref: '#\/components\/schemas\/Book'\n *       500:\n *         description: Some server error\n *\n *\/\n<\/pre>\n<p>Let\u2019s analyze it in parts, starting with the Swagger tags. A tag allows you to create a section within the Swagger docs. All the routes assigned to this tag will appear under the same division. It\u2019s an organizational setting.<\/p>\n<p>In our example, all the endpoints will be mapped to the same tag. Next, we set up our first route: the book\u2019s creation. It\u2019s pretty straightforward. First, define a <code>title<\/code> and specify the <code>tag<\/code> to which the path will be attached.<\/p>\n<p>Then, we have the request and the response. Within the request, define three things: whether the request is required, the content type of the request, and the schema from which it must be processed.<\/p>\n<p>The schemas can be referenced through the <code>#components\/schemas<\/code> Swagger operator. As for the response, define the HTTP response codes and the properties for each of them. We\u2019re just worried about the happy path with an <code>HTTP 200<\/code>.<\/p>\n<p>Go ahead and test the new operation directly within the Swagger UI page:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152179\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-book-working.gif\" alt=\"Documenting Express.js API with Swagger Full Example\" width=\"730\" height=\"507\"><\/p>\n<p>Now, you can see where the example values take place. It\u2019s easier to provide your users with sample data as a reference for when they want to perform stuff.<\/p>\n<p>Below, you can find the code for all the other operations:<\/p>\n<pre class=\"language-javascript hljs\">\/**\n * @swagger\n * tags:\n *   name: Books\n *   description: The books managing API\n * \/books:\n *   get:\n *     summary: Lists all the books\n *     tags: [Books]\n *     responses:\n *       200:\n *         description: The list of the books\n *         content:\n *           application\/json:\n *             schema:\n *               type: array\n *               items:\n *                 $ref: '#\/components\/schemas\/Book'\n *   post:\n *     summary: Create a new book\n *     tags: [Books]\n *     requestBody:\n *       required: true\n *       content:\n *         application\/json:\n *           schema:\n *             $ref: '#\/components\/schemas\/Book'\n *     responses:\n *       200:\n *         description: The created book.\n *         content:\n *           application\/json:\n *             schema:\n *               $ref: '#\/components\/schemas\/Book'\n *       500:\n *         description: Some server error\n * \/books\/{id}:\n *   get:\n *     summary: Get the book by id\n *     tags: [Books]\n *     parameters:\n *       - in: path\n *         name: id\n *         schema:\n *           type: string\n *         required: true\n *         description: The book id\n *     responses:\n *       200:\n *         description: The book response by id\n *         contens:\n *           application\/json:\n *             schema:\n *               $ref: '#\/components\/schemas\/Book'\n *       404:\n *         description: The book was not found\n *   put:\n *    summary: Update the book by the id\n *    tags: [Books]\n *    parameters:\n *      - in: path\n *        name: id\n *        schema:\n *          type: string\n *        required: true\n *        description: The book id\n *    requestBody:\n *      required: true\n *      content:\n *        application\/json:\n *          schema:\n *            $ref: '#\/components\/schemas\/Book'\n *    responses:\n *      200:\n *        description: The book was updated\n *        content:\n *          application\/json:\n *            schema:\n *              $ref: '#\/components\/schemas\/Book'\n *      404:\n *        description: The book was not found\n *      500:\n *        description: Some error happened\n *   delete:\n *     summary: Remove the book by id\n *     tags: [Books]\n *     parameters:\n *       - in: path\n *         name: id\n *         schema:\n *           type: string\n *         required: true\n *         description: The book id\n *\n *     responses:\n *       200:\n *         description: The book was deleted\n *       404:\n *         description: The book was not found\n *\/\n<\/pre>\n<p>Ideally, those mappings should be placed above each Express.js routing function. However, we\u2019re concentrating them in a single place for simplicity.<\/p>\n<h3 id=\"mapping-endpoints\">Mapping the endpoints<\/h3>\n<p>Now, we\u2019re segregating the operations under two main categories: the ones that receive an <code>id<\/code> parameter and those that do not. That\u2019s necessary for Swagger to understand how to match the routes with the proper path params.<\/p>\n<p>Whenever you have parameters in your endpoints, regardless of their type, you must inform the details under the <code>parameters<\/code> property.<\/p>\n<p>Here\u2019s the result with all the endpoints correctly mapped:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152182\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-book-api.png\" alt=\"Correctly Mapped Endpoints in Express.js API with Swagger\" width=\"730\" height=\"569\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-book-api.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/express-js-swagger-book-api-300x234.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<h2 id=\"swagger-customization-css\">Swagger customization with CSS<\/h2>\n<p>You can customize Swagger UI by implementing a custom CSS into Swagger integration. To do that, add <code>customCssUrl<\/code> option into <code>swaggerUi.setup<\/code>:<\/p>\n<pre class=\"language-javascript hljs\">app.use(\n  \"\/api-docs\",\n  swaggerUi.serve,\n  swaggerUi.setup(specs, {\n    explorer: true,\n    customCssUrl:\n      \"https:\/\/cdn.jsdelivr.net\/npm\/swagger-ui-themes@3.0.0\/themes\/3.x\/theme-newspaper.css\",\n  })\n);\n<\/pre>\n<p>Here, we pass the custom CSS file into <code>customCssUrl<\/code> option. It will change the Swagger UI with custom styling.<\/p>\n<p>Here\u2019s how it will look before the custom CSS file:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-152184 size-full\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/swagger-custom-css-before.png\" alt=\"Before Customizing Your Express.js API in Swagger with CSS\" width=\"730\" height=\"388\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/swagger-custom-css-before.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/swagger-custom-css-before-300x159.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<p>Now, take a look at what it will look like after:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-152186\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/swagger-custom-css-after.png\" alt=\"After Customizing Your Express.js API in Swagger with CSS\" width=\"730\" height=\"403\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/swagger-custom-css-after.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/swagger-custom-css-after-300x166.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>You may test each endpoint individually to ensure it\u2019s working precisely as your <a href=\"https:\/\/blog.logrocket.com\/how-automate-api-tests-postman\/\">Postman<\/a> requests.<\/p>\n<p>Swagger is capable of way more than merely documenting your APIs. A quick read over the <a href=\"https:\/\/swagger.io\/docs\/\">official docs<\/a> will give you a better understanding of its power. Remember that documenting should be part of your team culture. Otherwise, your docs won\u2019t always be up to date.<\/p>\n<p>You can find the complete source code <a href=\"https:\/\/github.com\/ganeshmani\/swagger-nodejs-tutorial\">here<\/a>. Good luck!<\/p>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p> In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.<\/p>\n","protected":false},"author":156415316,"featured_media":152192,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2147999,1],"tags":[2109699],"class_list":["post-24092","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev","category-uncategorized","tag-node"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.1.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Documenting your Express API with Swagger - LogRocket Blog<\/title>\n<meta name=\"description\" content=\"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Documenting your Express API with Swagger - LogRocket Blog\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/\" \/>\n<meta property=\"og:site_name\" content=\"LogRocket Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-09T15:30:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-04T21:02:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png\" \/>\n\t<meta property=\"og:image:width\" content=\"730\" \/>\n\t<meta property=\"og:image:height\" content=\"487\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Diogo Souza\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Diogo Souza\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/\",\"url\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/\",\"name\":\"Documenting your Express API with Swagger - LogRocket Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.logrocket.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png\",\"datePublished\":\"2022-12-09T15:30:34+00:00\",\"dateModified\":\"2024-06-04T21:02:19+00:00\",\"author\":{\"@id\":\"https:\/\/blog.logrocket.com\/#\/schema\/person\/aeabeb4085a597a7abcc823c0fc89d7c\"},\"description\":\"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#primaryimage\",\"url\":\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png\",\"contentUrl\":\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png\",\"width\":730,\"height\":487,\"caption\":\"Documenting Express.js API With Swagger\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.logrocket.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Documenting your Express API with Swagger\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.logrocket.com\/#website\",\"url\":\"https:\/\/blog.logrocket.com\/\",\"name\":\"LogRocket Blog\",\"description\":\"Resources to Help Product Teams Ship Amazing Digital Experiences\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.logrocket.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.logrocket.com\/#\/schema\/person\/aeabeb4085a597a7abcc823c0fc89d7c\",\"name\":\"Diogo Souza\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.logrocket.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6e7379286a2bbd53c5fa8e5cee7d5cca97bad6e4b2f0f61cfd50a6315f7b53f7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6e7379286a2bbd53c5fa8e5cee7d5cca97bad6e4b2f0f61cfd50a6315f7b53f7?s=96&d=mm&r=g\",\"caption\":\"Diogo Souza\"},\"description\":\"Brazilian dev. Creator of altaluna.com.br\",\"sameAs\":[\"https:\/\/www.altaluna.com.br\/\"],\"url\":\"https:\/\/blog.logrocket.com\/author\/diogosouza\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Documenting your Express API with Swagger - LogRocket Blog","description":"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/","og_locale":"en_US","og_type":"article","og_title":"Documenting your Express API with Swagger - LogRocket Blog","og_description":"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.","og_url":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/","og_site_name":"LogRocket Blog","article_published_time":"2022-12-09T15:30:34+00:00","article_modified_time":"2024-06-04T21:02:19+00:00","og_image":[{"width":730,"height":487,"url":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png","type":"image\/png"}],"author":"Diogo Souza","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Diogo Souza","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/","url":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/","name":"Documenting your Express API with Swagger - LogRocket Blog","isPartOf":{"@id":"https:\/\/blog.logrocket.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#primaryimage"},"image":{"@id":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png","datePublished":"2022-12-09T15:30:34+00:00","dateModified":"2024-06-04T21:02:19+00:00","author":{"@id":"https:\/\/blog.logrocket.com\/#\/schema\/person\/aeabeb4085a597a7abcc823c0fc89d7c"},"description":"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.","breadcrumb":{"@id":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#primaryimage","url":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png","contentUrl":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2020\/09\/documenting-express-js-api-swagger.png","width":730,"height":487,"caption":"Documenting Express.js API With Swagger"},{"@type":"BreadcrumbList","@id":"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.logrocket.com\/"},{"@type":"ListItem","position":2,"name":"Documenting your Express API with Swagger"}]},{"@type":"WebSite","@id":"https:\/\/blog.logrocket.com\/#website","url":"https:\/\/blog.logrocket.com\/","name":"LogRocket Blog","description":"Resources to Help Product Teams Ship Amazing Digital Experiences","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.logrocket.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.logrocket.com\/#\/schema\/person\/aeabeb4085a597a7abcc823c0fc89d7c","name":"Diogo Souza","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.logrocket.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6e7379286a2bbd53c5fa8e5cee7d5cca97bad6e4b2f0f61cfd50a6315f7b53f7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6e7379286a2bbd53c5fa8e5cee7d5cca97bad6e4b2f0f61cfd50a6315f7b53f7?s=96&d=mm&r=g","caption":"Diogo Souza"},"description":"Brazilian dev. Creator of altaluna.com.br","sameAs":["https:\/\/www.altaluna.com.br\/"],"url":"https:\/\/blog.logrocket.com\/author\/diogosouza\/"}]}},"yoast_description":"In this tutorial, we will explore maintaining thorough API documentation using Swagger with an Express.js API in Node.js.","_links":{"self":[{"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts\/24092","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/users\/156415316"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/comments?post=24092"}],"version-history":[{"count":21,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts\/24092\/revisions"}],"predecessor-version":[{"id":153512,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts\/24092\/revisions\/153512"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/media\/152192"}],"wp:attachment":[{"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/media?parent=24092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/categories?post=24092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/tags?post=24092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}