{"id":167122,"date":"2023-04-12T12:00:22","date_gmt":"2023-04-12T16:00:22","guid":{"rendered":"https:\/\/blog.logrocket.com\/?p=167122"},"modified":"2024-06-04T16:59:26","modified_gmt":"2024-06-04T20:59:26","slug":"write-scalable-openapi-specification-node-js","status":"publish","type":"post","link":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/","title":{"rendered":"Write a scalable OpenAPI specification for a Node.js API"},"content":{"rendered":"<!DOCTYPE html>\n<html><p>If you\u2019ve ever done an API integration, you\u2019d know it. Whenever something breaks or doesn\u2019t work, an API owner needs to communicate a bunch of basic details, including status codes, happy paths, required parameters, and authentication mechanisms.<\/p><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"487\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png\" class=\"attachment-full size-full wp-post-image\" alt=\"Node JS Ope API Spec\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec-300x200.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\">\n<p>This approach requires a constant context switch and is clearly not productive. Here, the <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\">OpenAPI Specification<\/a> can help; you might already have it, but is it scalable? In this article, we\u2019ll learn how to create an OpenAPI Specification document that is readable, scalable, and follows the principle of extension without modifying the existing document.<\/p>\n<p>We\u2019ll use a <a href=\"https:\/\/github.com\/Rishabh570\/nodejs-openapi-spec\">sample Node.js API<\/a> that uses the Express framework. We\u2019ll write the specification document for this API and learn how to create a scalable and easy-to-maintain OpenAPI specification along the way. Let\u2019s get started!<\/p>\n<p><em>Jump ahead:<\/em><\/p>\n<ul>\n<li><a href=\"#openapi-specification\">What is the OpenAPI Specification?<\/a><\/li>\n<li><a href=\"#why-write-open-api-specification\">Why write an OpenAPI Specification?<\/a><\/li>\n<li><a href=\"#open-api-specification-look-like\">What does an OpenAPI Specification look like?<\/a><\/li>\n<li><a href=\"#writing-specification-sample-api\">Writing a specification for our sample Node.js API<\/a><\/li>\n<li><a href=\"#writing-possible-responses\">Writing possible responses<\/a><\/li>\n<li><a href=\"#best-practices-writing-specification\">Best practices for writing an OpenAPI Specification<\/a><\/li>\n<li><a href=\"#visualizing-specification-swagger-ui\">Visualizing the specification with Swagger UI<\/a><\/li>\n<\/ul>\n<h2 id=\"openapi-specification\">What is the OpenAPI Specification?<\/h2>\n<p>When it comes to working with any API, we all know how important having a well-written documentation is. An incomplete, or worse, incorrect documentation results in&nbsp;wasted time and effort.<\/p>\n<p>The OpenAPI Specification aims to solve this problem by providing a standard, language-agnostic interface to understand and interact with the API in a way that is easier for both humans and computers.<\/p>\n<p>An OpenAPI specification document describes the complete API in an industry-standard manner. It is battle-tested, meaning you won\u2019t miss out on any useful information.<\/p>\n<h2 id=\"why-write-open-api-specification\">Why write an OpenAPI specification?<\/h2>\n<p>In a world where we\u2019re constantly working on the next big thing, it\u2019s pretty boring to spend time writing documentation. However, having detailed written documentation can benefit the rest of your team as well as any end users. Writing scales, and anyone can refer to the documentation and understand the API from the inside-out.<\/p>\n<p>This alone is enough motivation to incorporate an OpenAPI specification in your APIs. But, the benefits don\u2019t stop there. For one, by providing the specification, you can generate API code in any language, which helps in quick prototyping if you want to replicate any API using a different programming language.<\/p>\n<p>In addition, because the specification is aware of all the possible request parameters and corresponding responses, you can use it to generate test cases for your API and make sure your API is working as expected.<\/p>\n<h2 id=\"open-api-specification-look-like\">What does an OpenAPI specification look like?<\/h2>\n<p>An OpenAPI specification consists of several different components, each having a dedicated and important purpose. Let\u2019s take a look at each one.<\/p>\n<h3><code>info<\/code><\/h3>\n<p>The <code>info<\/code> object provides metadata about the API, like its title, version, and contact information. You can use this information to identify the API and understand its purpose.<\/p>\n<h3><code>server<\/code><\/h3>\n<p>The <code>server<\/code> object describes the URLs of the API, including the base URL as well as any variables that are used in the URL.<\/p>\n<h3><code>paths<\/code><\/h3>\n<p>The <code>paths<\/code> object describes the endpoints of the API and the operations that can be performed on them. This includes the <a href=\"https:\/\/blog.logrocket.com\/crud-rest-api-node-js-express-postgresql\/\">HTTP methods, like <code>GET<\/code>, <code>POST<\/code>, and <code>PUT<\/code><\/a>, as well as the parameters and responses for each endpoint.<\/p>\n<h3><code>components<\/code><\/h3>\n<p>The <code>components<\/code> object is a container for reusable objects like schemas, examples, and security schemes. You can reference these objects from elsewhere in the specification, making it easier to maintain and update the specification.<\/p>\n<h3>Schemas<\/h3>\n<p>Schemas help you define the data type of <code>input<\/code> and <code>output<\/code> objects. Any request parameter, request body, or response object that you use in the specification can be abstracted as a schema object and reused wherever required.<\/p>\n<p>A schema object can be understood as a variable in your Node.js application. Both promote reusability but aren\u2019t involved unless used in the code.<\/p>\n<h3><code>responses<\/code><\/h3>\n<p>The <code>responses<\/code> object contains all the possible API responses mapped to the HTTP status code.<\/p>\n<h3><code>security<\/code><\/h3>\n<p>The <code>security<\/code> object describes the security requirements for the API, including the types of authentication and authorization that are supported, as well as the scopes that are required for different operations.<\/p>\n<h3><code>tags<\/code><\/h3>\n<p>The <code>tags<\/code> object describes a list of tags used by the specification with additional metadata. This can be used to group related endpoints together and organize the specification.<\/p>\n<h2 id=\"writing-specification-sample-api\">Writing a specification for our sample Node.js API<\/h2>\n<p>Now that we have the basic understanding of the OpenAPI Specification, why it is important, and what components comprise it, let\u2019s document our sample Node.js API.<\/p>\n<p>It\u2019s very important to make sure that the specification is scalable. Putting everything inside of a single file defeats the purpose of human readability, but unfortunately, it is a common practice.<\/p>\n<p>We\u2019ll create a better, more human-readable specification that achieves all of the things it promises. Before we get to it, let\u2019s make sure to create a <code>docs\/<\/code> folder at the root of the project. The folder structure looks like the following:<\/p>\n<pre class=\"language-shell hljs\">|- docs\/\n|----schemas\/\n|----responses\/\n|----paths\/\n|----index.json\n|- src\/\n|- package.json\n|- package-lock.json\n<\/pre>\n<p>Once it\u2019s done, we can install the required dependencies.<\/p>\n<h3>Installing dependencies<\/h3>\n<p>We\u2019ll need two packages to create a scalable OpenAPI specification; run the following command to install them:<\/p>\n<pre class=\"language-node hljs\">npm install @apidevtools\/swagger-cli\n<\/pre>\n<h3>Creating a schema<\/h3>\n<p>We need to create schemas for the common and reusable entities in our REST API. Since we only have one major entity, we\u2019ll create a schema for <code>Item<\/code> in <code>docs\/schemas\/item.json<\/code>:<\/p>\n<pre class=\"language-json hljs\">{\n  \"type\": \"object\",\n  \"required\": [\"name\", \"hash\", \"rating\", \"price\"],\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\"\n    },\n    \"rating\": {\n     \"type\": \"string\",\n      \"example\": \"4\"\n    },\n    \"price\": {\n      \"type\": \"number\"\n    },\n    \"hash\": {\n      \"type\": \"string\"\n    }\n  }\n}\n<\/pre>\n<h2 id=\"writing-possible-responses\">Writing possible responses<\/h2>\n<p>There are three possible responses that our API will return to the clients:<\/p>\n<ol>\n<li><code>200<\/code>: Success<\/li>\n<li><code>500<\/code>: Internal server error<\/li>\n<li><code>400<\/code>: Bad request<\/li>\n<\/ol>\n<p>Keeping our API\u2019s behavior in mind, we\u2019ll create three response files documenting these scenarios.<\/p>\n<h3>Successful response<\/h3>\n<p>For a successful API response, we\u2019ll use the code below:<\/p>\n<pre class=\"language-json hljs\">{\n  \"description\": \"Response for operation successful\",\n  \"content\": {\n   \"application\/json\": {\n      \"schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"message\": {\n            \"type\": \"boolean\",\n            \"enum\": [true],\n            \"example\": true\n          },\n          \"item\": {\n            \"$ref\": \"..\/schemas\/item.json\"\n          }\n        }\n      }\n    }\n  }  \n}\n<\/pre>\n<h3>Internal server error<\/h3>\n<p>While your API serves a request, issues can occur. For example, the database connection might time out, the network connection can get lost, your API might over-utilize resources like CPU, RAM, etc., causing a shutdown.<\/p>\n<p>Whenever our API fails to serve the request, by no fault of the client, we return an internal server error response, a 500 HTTP status. Below is our specification document for such an error:<\/p>\n<pre class=\"language-json hljs\">{\n  \"description\": \"Response for operation successful\",\n  \"content\": {\n    \"application\/json\": {\n      \"schema\": {\n        \"type\": \"object\",\n       \"properties\": {\n        \"message\": {\n         \"type\": \"string\",\n            \"example\": \"Something went wrong while creating a new item!\"\n          },\n          \"item\": {\n            \"type\": \"object\",\n            \"enum\": [null]\n          }\n        }\n     }\n   }\n  }  \n}\n<\/pre>\n<h3>Bad request<\/h3>\n<p>And, finally, we give a bad request response to the client if it passes invalid or incompatible details that break our API contract:<\/p>\n<pre class=\"language-json hljs\">{\n  \"description\": \"Response for operation successful\",\n  \"content\": {\n    \"application\/json\": {\n      \"schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"message\": {\n            \"type\": \"string\",\n           \"example\": \"Something went wrong while creating a new item!\"\n         },\n         \"item\": {\n            \"type\": \"object\",\n            \"enum\": [null]\n          }\n        }\n      }\n    }\n  }  \n}\n<\/pre>\n<h3>Adding security schema<\/h3>\n<p>The sample API doesn\u2019t enforce any form of authentication. That\u2019s not our goal; the goal is to understand how to write the specification, which can handle authentication. To solve this issue, we\u2019ll require an authentication header with a bearer token scheme and apply it globally.<\/p>\n<p>Below is our security schema:<\/p>\n<pre class=\"language-json hljs\">{\n  \"bearerAuth\": {\n      \"type\": \"http\",\n    \"description\": \"JWT authorization header using the bearer scheme\",\n     \"scheme\": \"bearer\",\n      \"bearerFormat\": \"JWT\"\n  }\n}\n<\/pre>\n<p>You can make authentication mandatory by adding it to the root of your OpenAPI specification document:<\/p>\n<pre class=\"language-json hljs\">\"security\": [\n    {\n        \"bearerAuth\": []\n    }\n  ]\n<\/pre>\n<h3>Putting it all together in the paths section<\/h3>\n<p>Finally, add the following scripts in the <code>package.json<\/code> file:<\/p>\n<pre class=\"language-json hljs\">\"scripts\": {\n  \"docs:debug\": \"swagger-cli validate -d docs\/index.json\",\n  \"docs:generate\": \"swagger-cli bundle docs\/index.json --outfile openapi.json\",\n}\n<\/pre>\n<p>To generate the final OpenAPI specification file, simply run the following command:<\/p>\n<pre class=\"language-shell hljs\">npm run docs:generate\n<\/pre>\n<p>To validate your specification for syntactical correctness, run the code below:<\/p>\n<pre class=\"language-shell hljs\">npm run docs:debug\n<\/pre>\n<p>You can even choose to combine the validation and specification generation commands to automatically validate the specification every time you generate one:<\/p>\n<pre class=\"language-json hljs\">\"scripts\": {\n  \"docs:debug\": \"swagger-cli validate -d docs\/index.json\",\n  \"docs:generate\": \"npm run docs:debug &amp;&amp; swagger-cli bundle docs\/index.json --outfile openapi.json\",\n}\n<\/pre>\n<p>You can also automate the OpenAPI specification generation by adding the <code>docs:generate<\/code> script above to your <a href=\"https:\/\/blog.logrocket.com\/build-robust-react-app-husky-pre-commit-hooks-github-actions\/\">Husky pre-commit hook<\/a>. Therefore, you\u2019ll always have a valid and up-to-date specification on every commit:<\/p>\n<pre class=\"language-json hljs\">\"husky\": {\n    \"hooks\": {\n      \"commit-msg\": \"commitlint -E HUSKY_GIT_PARAMS\",\n      \"pre-commit\": \"npm run docs:generate &amp;&amp; npm run codefix &amp;&amp; git add .\"\n    }\n  }\n<\/pre>\n<p>Why wouldn\u2019t any automation enthusiast do this? I\u2019ve already added this to the sample Node.js API, so you can clone the project and play around with it.<\/p>\n<h2 id=\"best-practices-writing-specification\">Best practices for writing an OpenAPI specification<\/h2>\n<p>With that, we\u2019ve finished writing our OpenAPI Specification, and it looks clean. There are certain practices that we should follow to increase the quality of our specification and ensure that it\u2019s scalable.<\/p>\n<h3>Don\u2019t add redundant context in names<\/h3>\n<p>When writing schemas, responses, or any other component of the specification, you should avoid adding unnecessary context that complicates the name. For example, using <code>response\/success.json<\/code> is much more concise and readable than <code>response\/successResponseFromHTTPRequest.json<\/code>.<\/p>\n<h3>Choose generic responses whenever possible<\/h3>\n<p>When creating response components for your OpenAPI Specification, you should try to make the responses as generalized as possible as long as it doesn\u2019t contradict the way your API is written. This promotes reusability and makes your specification scalable.<\/p>\n<h2 id=\"visualizing-specification-swagger-ui\">Visualizing the specification with Swagger UI<\/h2>\n<p>You can use the specification file and share it with other teams during integration requirements. <a href=\"https:\/\/blog.logrocket.com\/documenting-express-js-api-swagger\/\">Swagger UI makes the specification interactive<\/a>, so it\u2019s easier to consume and understand.<\/p>\n<p>Since we\u2019ve already created the specification, it\u2019s just a matter of plugging the <a href=\"https:\/\/www.npmjs.com\/package\/swagger-ui-express\">Swagger UI Express<\/a> package and creating a dedicated route to host the interactive documentation. First, let\u2019s install it:<\/p>\n<pre class=\"language-bash hljs\">npm install swagger-ui-express\n<\/pre>\n<p>Once it\u2019s done installing, create a route for hosting the documentation with the code below:<\/p>\n<pre class=\"language-javascript hljs\">const swaggerUi = require('swagger-ui-express');\nconst openApiDocumentation = require('..\/openapi.json');\napp.use('\/docs, swaggerUi.serve, swaggerUi.setup(openApiDocumentation));\n<\/pre>\n<p>And with that, we\u2019re done! You can now visit the URL and start interacting with the documentation:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-167132 size-full\" src=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/visit-node-js-api-sample-url-open-api-spec.png\" alt=\"Visit Nodejs API Sample URL Open API Spec\" width=\"730\" height=\"379\" srcset=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/visit-node-js-api-sample-url-open-api-spec.png 730w, https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/visit-node-js-api-sample-url-open-api-spec-300x156.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this tutorial, we\u2019ve successfully created a scalable OpenAPI specification for our sample Node.js API. Instead of just blindly following the OpenAPI specification trend, we first reviewed it in detail. I hope that this article helped you understand why the OpenAPI Specification is essential and learn how you can write one for your Node.js applications.<\/p>\n<p>If you have any questions, feel free to leave a comment below. Happy coding!<\/p>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>The OpenAPI specification provides a standard, language-agnostic interface to understand and interact with the API in a way that is easier for both humans and computers.<\/p>\n","protected":false},"author":156416065,"featured_media":167126,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2147999,1],"tags":[2109699],"class_list":["post-167122","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>Write a scalable OpenAPI specification for a Node.js API - LogRocket Blog<\/title>\n<meta name=\"description\" content=\"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.\" \/>\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\/write-scalable-openapi-specification-node-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Write a scalable OpenAPI specification for a Node.js API - LogRocket Blog\" \/>\n<meta property=\"og:description\" content=\"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/\" \/>\n<meta property=\"og:site_name\" content=\"LogRocket Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-12T16:00:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-04T20:59:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.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=\"Rishabh Rawat\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/Rishabh570\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rishabh Rawat\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/\",\"url\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/\",\"name\":\"Write a scalable OpenAPI specification for a Node.js API - LogRocket Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.logrocket.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png\",\"datePublished\":\"2023-04-12T16:00:22+00:00\",\"dateModified\":\"2024-06-04T20:59:26+00:00\",\"author\":{\"@id\":\"https:\/\/blog.logrocket.com\/#\/schema\/person\/67d6b0763e2cf67c8d70ffec2630bd9a\"},\"description\":\"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#primaryimage\",\"url\":\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png\",\"contentUrl\":\"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png\",\"width\":730,\"height\":487,\"caption\":\"Node JS Ope API Spec\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.logrocket.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Write a scalable OpenAPI specification for a Node.js API\"}]},{\"@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\/67d6b0763e2cf67c8d70ffec2630bd9a\",\"name\":\"Rishabh Rawat\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.logrocket.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c2e9f02273b71b1a79a23b7abfca753fea8f9935651a2d1b4cf304d45da9528f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c2e9f02273b71b1a79a23b7abfca753fea8f9935651a2d1b4cf304d45da9528f?s=96&d=mm&r=g\",\"caption\":\"Rishabh Rawat\"},\"description\":\"Rishabh is a full-time Software Engineer, GSoC '19 participant, and GCI '18 mentor. He writes about backend web development biweekly. Find him on Twitter and LinkedIn.\",\"sameAs\":[\"https:\/\/rrawat.com\/\",\"https:\/\/www.linkedin.com\/in\/rishabh570\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/Rishabh570\"],\"url\":\"https:\/\/blog.logrocket.com\/author\/rishabhrawat\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Write a scalable OpenAPI specification for a Node.js API - LogRocket Blog","description":"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.","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\/write-scalable-openapi-specification-node-js\/","og_locale":"en_US","og_type":"article","og_title":"Write a scalable OpenAPI specification for a Node.js API - LogRocket Blog","og_description":"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.","og_url":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/","og_site_name":"LogRocket Blog","article_published_time":"2023-04-12T16:00:22+00:00","article_modified_time":"2024-06-04T20:59:26+00:00","og_image":[{"width":730,"height":487,"url":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png","type":"image\/png"}],"author":"Rishabh Rawat","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/Rishabh570","twitter_misc":{"Written by":"Rishabh Rawat","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/","url":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/","name":"Write a scalable OpenAPI specification for a Node.js API - LogRocket Blog","isPartOf":{"@id":"https:\/\/blog.logrocket.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#primaryimage"},"image":{"@id":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png","datePublished":"2023-04-12T16:00:22+00:00","dateModified":"2024-06-04T20:59:26+00:00","author":{"@id":"https:\/\/blog.logrocket.com\/#\/schema\/person\/67d6b0763e2cf67c8d70ffec2630bd9a"},"description":"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.","breadcrumb":{"@id":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#primaryimage","url":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png","contentUrl":"https:\/\/blog.logrocket.com\/wp-content\/uploads\/2023\/04\/node-js-open-api-spec.png","width":730,"height":487,"caption":"Node JS Ope API Spec"},{"@type":"BreadcrumbList","@id":"https:\/\/blog.logrocket.com\/write-scalable-openapi-specification-node-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.logrocket.com\/"},{"@type":"ListItem","position":2,"name":"Write a scalable OpenAPI specification for a Node.js API"}]},{"@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\/67d6b0763e2cf67c8d70ffec2630bd9a","name":"Rishabh Rawat","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.logrocket.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c2e9f02273b71b1a79a23b7abfca753fea8f9935651a2d1b4cf304d45da9528f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c2e9f02273b71b1a79a23b7abfca753fea8f9935651a2d1b4cf304d45da9528f?s=96&d=mm&r=g","caption":"Rishabh Rawat"},"description":"Rishabh is a full-time Software Engineer, GSoC '19 participant, and GCI '18 mentor. He writes about backend web development biweekly. Find him on Twitter and LinkedIn.","sameAs":["https:\/\/rrawat.com\/","https:\/\/www.linkedin.com\/in\/rishabh570\/","https:\/\/x.com\/https:\/\/twitter.com\/Rishabh570"],"url":"https:\/\/blog.logrocket.com\/author\/rishabhrawat\/"}]}},"yoast_description":"Create an OpenAPI specification that is readable, scalable, and follows the principle of extension without modifying the existing document.","_links":{"self":[{"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts\/167122","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\/156416065"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/comments?post=167122"}],"version-history":[{"count":15,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts\/167122\/revisions"}],"predecessor-version":[{"id":167914,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/posts\/167122\/revisions\/167914"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/media\/167126"}],"wp:attachment":[{"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/media?parent=167122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/categories?post=167122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.logrocket.com\/wp-json\/wp\/v2\/tags?post=167122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}