API Documentation with Swagger
Why API Documentation Matters
Every API you build will eventually be used by someone else — a frontend developer on your team, a mobile app developer, or a third-party integrator. Without documentation, they have to guess what endpoints exist, what parameters they accept, and what responses they return. This creates friction, bugs, and endless Slack messages to the backend team.
Good API documentation is not optional for professional projects. It is part of the deliverable.
OpenAPI: The Industry Standard
OpenAPI (formerly known as Swagger) is the most widely used specification for describing REST (Representational State Transfer) APIs. An OpenAPI document describes:
- All available endpoints and their HTTP methods
- Request parameters, headers, and body schemas
- Response shapes for each status code
- Authentication requirements
- Example values
The OpenAPI specification is written in JSON or YAML (YAML Ain't Markup Language) format. Tools can read this file to generate interactive documentation, client SDKs, and automated tests.
Setting Up swagger-jsdoc and swagger-ui-express
Instead of writing the OpenAPI YAML file by hand, you write JSDoc comments directly in your route files. swagger-jsdoc scans those comments and generates the OpenAPI document automatically.
npm install swagger-jsdoc swagger-ui-express
Base Configuration
Create a swagger.js configuration file:
// config/swagger.js
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'CareerEx API',
version: '1.0.0',
description: 'REST API for the CareerEx learning platform',
contact: {
name: 'CareerEx Dev Team',
email: 'api@careerex.io',
},
},
servers: [
{ url: 'http://localhost:5000/api/v1', description: 'Development' },
{ url: 'https://api.careerex.io/v1', description: 'Production' },
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
},
},
apis: ['./routes/*.js'], // files containing JSDoc comments
};
module.exports = swaggerJsdoc(options);
Mount the UI in app.js
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./config/swagger');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
Visit http://localhost:5000/api-docs to see the interactive documentation UI.
Writing JSDoc Comments That Generate Documentation
Annotate your routes with @swagger comments using the OpenAPI 3.0 syntax:
// routes/users.js
/**
* @swagger
* /users:
* get:
* summary: Retrieve a list of users
* description: Returns a paginated list of all registered users.
* tags: [Users]
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: Page number
* - in: query
* name: limit
* schema:
* type: integer
* default: 20
* description: Number of results per page
* responses:
* 200:
* description: Users retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* data:
* type: array
* items:
* $ref: '#/components/schemas/User'
* 500:
* description: Internal server error
*/
router.get('/', getUsers);
Defining Reusable Schemas
Define schemas once in a models file and reference them with $ref throughout your documentation:
// models/User.js (or a dedicated schemas file)
/**
* @swagger
* components:
* schemas:
* User:
* type: object
* required:
* - name
* - email
* properties:
* id:
* type: string
* description: MongoDB ObjectId
* example: 64a3f1c2b8e4a1234567abcd
* name:
* type: string
* example: Amara Okafor
* email:
* type: string
* format: email
* example: amara@example.com
* createdAt:
* type: string
* format: date-time
*/
Documenting a Protected Endpoint
/**
* @swagger
* /users/{id}:
* delete:
* summary: Delete a user
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* description: The user ID
* responses:
* 204:
* description: User deleted successfully
* 401:
* description: Unauthorized
* 404:
* description: User not found
*/
router.delete('/:id', protect, deleteUser);
Exporting the Raw OpenAPI Spec
Frontend teams or third-party integrators may want the raw JSON spec to import into tools like Postman or Insomnia:
app.get('/api-docs.json', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send(swaggerSpec);
});
Practice Exercise
- Install
swagger-jsdocandswagger-ui-expressin your Express project. - Create a
config/swagger.jsfile with your project's title, version, and server URLs. - Add JSDoc comments to at least two routes: one GET (list endpoint) and one POST (create endpoint).
- Define a reusable schema for your primary resource (e.g.
UserorProduct). - Visit
/api-docsin your browser and confirm the endpoints appear and can be tested interactively.
Try it yourself
Key Takeaways
- API documentation is part of the deliverable — not an optional extra — especially when other developers or teams consume your API.
- OpenAPI (formerly Swagger) is the industry standard specification for describing REST APIs.
- swagger-jsdoc generates an OpenAPI document from JSDoc comments; swagger-ui-express serves an interactive UI from that document.
- Define reusable schemas in components/schemas and reference them with $ref to keep documentation consistent.
- Expose a /api-docs.json endpoint so external tools like Postman can import your specification directly.
Quick Quiz
1.What does swagger-jsdoc do in a Node.js project?
2.Why is it better to define reusable schemas with $ref instead of repeating them in every endpoint?
3.Which OpenAPI version do swagger-jsdoc projects typically use today?
4.What is the benefit of exposing a /api-docs.json endpoint alongside the Swagger UI?
Ready to go further?
CareerEx gives you structured 12-week training, live classes every Saturday and Sunday, real tutor feedback, and a certificate. Join the next cohort.
Join CareerEx