21 Swagger Docs
title: Swagger Documentation for Node.js REST APIs weight: 31 date: 2026-06-28 lastmod: 2026-06-28 description: Generate Swagger/OpenAPI documentation for Node.js REST APIs using swagger-jsdoc and swagger-ui-express with JSDoc annotations and automatic schema generation. tags: [api-development, nodejs]
Swagger documentation for Node.js REST APIs uses swagger-jsdoc to parse JSDoc annotations into OpenAPI specifications and swagger-ui-express to serve interactive API documentation with try-it-out functionality.
```mermaid
flowchart TD
A[JSDoc Comments] --> B[swagger-jsdoc]
B --> C[OpenAPI Spec]
C --> D[swagger-ui-express]
D --> E[Interactive Docs]
E --> F[/api-docs]
A --> G[Route definitions]
A --> H[Schema definitions]
A --> I[Response examples]
style A fill:#e1f5fe
style C fill:#fff9c4
style E fill:#c8e6c9
Document routes inline using JSDoc comments above route handlers. Define schemas separately for reusability. The swagger-jsdoc package scans your code for these comments and generates the OpenAPI JSON, which swagger-ui-express serves as interactive HTML documentation.
Think of JSDoc annotations like cooking recipe cards attached to each dish in a restaurant kitchen. The chef (developer) writes the recipe, and the menu (Swagger UI) presents it to customers in a readable format.
Example: Swagger Setup
const swaggerJsdoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const options = {
definition: {
openapi: '3.0.3',
info: {
title: 'My API',
version: '1.0.0',
description: 'REST API documentation'
},
servers: [
{ url: 'http://localhost:3000', description: 'Development' }
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT'
}
},
schemas: {
User: {
type: 'object',
required: ['name', 'email'],
properties: {
id: { type: 'string', description: 'User ID' },
name: { type: 'string', description: 'Full name' },
email: { type: 'string', format: 'email' },
role: { type: 'string', enum: ['user', 'admin'] }
}
},
Error: {
type: 'object',
properties: {
status: { type: 'string' },
error: {
type: 'object',
properties: {
code: { type: 'string' },
message: { type: 'string' }
}
}
}
}
}
}
},
apis: ['./src/routes/*.js']
};
const swaggerSpec = swaggerJsdoc(options);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
app.get('/api-docs.json', (req, res) => res.json(swaggerSpec));
Example: JSDoc Route Annotations
/**
* @swagger
* /api/users:
* get:
* summary: List all users
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* description: Page number
* - in: query
* name: limit
* schema:
* type: integer
* description: Items per page
* responses:
* 200:
* description: User list
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: string
* data:
* type: array
* items:
* $ref: '#/components/schemas/User'
*/
router.get('/users', authenticate, userController.listUsers);
/**
* @swagger
* /api/users/{id}:
* get:
* summary: Get user by ID
* tags: [Users]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: User details
* 404:
* description: User not found
*/
router.get('/users/:id', authenticate, userController.getUser);
Example: Request Body Annotation
/**
* @swagger
* /api/users:
* post:
* summary: Create a new user
* tags: [Users]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - name
* - email
* - password
* properties:
* name:
* type: string
* email:
* type: string
* format: email
* password:
* type: string
* format: password
* role:
* type: string
* enum: [user, admin]
* responses:
* 201:
* description: User created
* 400:
* description: Validation error
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
*/
router.post('/users', validate(userSchema), userController.createUser);
Common Mistakes
- Documentation out of sync with code — Update JSDoc annotations whenever route handlers change. Outdated documentation is worse than no documentation.
- Missing response examples — Every response should include an example. Developers understand examples faster than schema definitions.
- Not documenting error responses — Document every error code and response format so clients can handle failures correctly.
- Overly complex schemas — Keep schemas simple and reusable. Use $ref to compose complex schemas from smaller, reusable components.
- Not including authentication in documentation — Every protected endpoint should show the required security scheme. Add the lock icon in Swagger UI.
Practice Questions
- How do you generate OpenAPI specs from JSDoc comments?
- What is the purpose of $ref in OpenAPI schemas?
- How do you document authentication requirements?
- How do you serve Swagger UI in Express?
- Challenge: Document a complete CRUD API for products using swagger-jsdoc. Include all endpoints, request bodies, response schemas, error responses, authentication, and examples. Verify the spec with the Swagger Editor validator.
FAQ
Mini Project
Generate complete Swagger documentation for a blog API with posts, comments, users, and tags. Include: all CRUD endpoints with annotations, reusable schemas, authentication security scheme, request/response examples, error response documentation, and a custom theme for Swagger UI.
What's Next
Now learn about deployment with Docker in Building REST APIs with Node.js.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro