Introduction
In the previous lesson, you successfully configured your application to serve an interactive documentation page at the /api-docs endpoint. While the page is live, it currently shows "No operations defined," because we haven't described our API's data structures or endpoints yet.
This lesson addresses the first part of that: defining our data. We will create a reusable schema component for the primary resource your API will manage. Think of this as creating a template for your data model (e.g., a "Product," "User," or "Task") that Swagger can use to understand the shape of your API's inputs and outputs. This is a crucial step for maintaining clean, consistent, and easy-to-manage documentation—a core practice known as "Don't Repeat Yourself" (DRY).
By the end of this lesson, you will have defined a complete schema for your resource, including its properties, data types, required fields, and example values, which will appear in the "Schemas" section of your Swagger UI.
What is a Reusable Schema Component?
In OpenAPI/Swagger, a schema component is a definition of a data object that can be reused across multiple parts of your documentation. Instead of defining the structure of a "Product" object every time you mention it (in the response for "get all products," in the request for "create a new product," etc.), you define it once and then simply reference it.
We will define this component within a JSDoc comment block, right in our source code. The swagger-jsdoc package will find this block and add it to the final specification under the components.schemas path.
Let's watch a video that demonstrates this concept perfectly.
NodeJS Swagger API Documentation Tutorial Using Swagger JSDoc
This clip from Maksim Ivanov's tutorial clearly shows how to define a reusable schema for a 'Book' model. It covers the exact YAML structure you'll need: defining the type, required fields, properties, and an example object.
Watch from 12:20 to 14:45. Focus on how the JSDoc comment is structured with YAML to define the Book schema inside components.schemas.
Implementing the Schema
As you saw in the video, the schema is defined using YAML syntax inside a /** ... */ comment block. Let's break down the structure for our own resource. For this course, we will build an API to manage "Products."
The schema definition goes at the top of the relevant route file, which for us will be src/routes/productRoutes.js.
Here is the general structure:
/**
* @swagger
* components:
* schemas:
* Product:
* type: object
* required:
* - name
* - price
* properties:
* _id:
* type: string
* description: The auto-generated id of the product
* name:
* type: string
* description: The name of the product
* description:
* type: string
* description: The description of the product
* price:
* type: number
* description: The price of the product
* createdAt:
* type: string
* format: date-time
* description: The date the product was added
* example:
* _id: d5fE_asz
* name: "Sample Product"
* description: "This is a sample product description."
* price: 29.99
* createdAt: "2023-01-01T12:00:00.000Z"
*/
Let's analyze the key parts:
components: schemas: Product:: This path tellsswagger-jsdocto create a reusable schema namedProduct.type: object: Specifies that ourProductis a JSON object.required:: An array listing the fields that must be provided when creating or updating a product. This matches therequired: trueoption in your Mongoose schema.properties:: This is where each field of the model is defined._id,name,price, etc.: Each key is a property name.type: The data type (e.g.,string,number,integer,boolean). Note that MongoDB'sObjectIdis represented as astringin JSON. Dates are also represented asstringwith aformat: date-time.description: A brief explanation of the field's purpose.format: Provides more detail on thetype(e.g.,date-timefor ISO 8601 date strings).
example:: A complete example object. This is extremely helpful as it shows users of your API exactly what aProductobject looks like.
For another excellent code-based example, you can review the text resource below.
How to Document an Express API with Swagger UI and JSDoc
This article from Dev.to, 'How to Document an Express API with Swagger UI and JSDoc', provides another clear, text-based example of defining and referencing a reusable schema. It's a great reference to have open as you write your own.
Focus on section '3.4: Document the resources.' Notice how it defines a User schema under components/schemas and provides properties with types, descriptions, and examples. This pattern is exactly what we're implementing.
Your Turn: Define the Product Schema
Now, it's time to add this to your project.
- Open your main route file (e.g.,
src/routes/productRoutes.js). If you don't have this file yet, create it. - At the very top of the file, add the JSDoc comment block shown above. You can copy and paste it directly.
- Verification:
- Restart your server (
npm run devornode src/server.js). - Refresh the Swagger UI page in your browser (
http://localhost:YOUR_PORT/api-docs). - Scroll to the bottom. You should now see a "Schemas" section with your
Productmodel beautifully rendered, including its properties and the example payload.
- Restart your server (
It should look something like this:

A Critical Note on Indentation
YAML, the language used inside JSDoc for Swagger, is extremely sensitive to indentation. Every level of nesting must be indented by exactly two spaces. If your schema doesn't appear, or if you get errors later, the first thing to check is your indentation.
The TomDoesTech video Automatically Generate Swagger Docs With ExpressJS & NodeJS (resource ID LINK) highlights this perfectly between 28:18 and 28:43. An incorrect indent can cause the entire definition to be ignored by swagger-jsdoc without any explicit error in your console.
Correct:
properties:
_id:
type: string
Incorrect (will fail silently):
properties:
_id: // one space
type: string // four spaces
Conclusion
Excellent work. You have now defined a clean, reusable data model for your API documentation. This is a foundational practice that will dramatically speed up the process of documenting individual endpoints and ensure your API documentation is consistent and professional.
Key Takeaways:
- Reusable schemas are defined under
components: schemas:in your JSDoc comments. - Each schema should define its
type,requiredfields, andproperties(including theirtype,description, andexamplevalues). - A top-level
example:object provides a complete sample payload for users of your API. - YAML indentation is strict and must be correct (two spaces per level) for the schema to be parsed.
Next Up:
Our documentation page now knows what a Product is, but it still doesn't list any API operations. In the next lesson, we will put our new schema to use. We'll document our first endpoint—GET /api/products—and use a $ref to reference the Product schema, finally bringing your API operations to life in the Swagger UI.