API Documentation with Swagger/OpenAPI
Swagger (OpenAPI) enables you to design, document, and visualize RESTful APIs. Learn to create comprehensive API documentation that serves as both specification and interactive testing tool.
Challenge
Section titled “Challenge”Create comprehensive API documentation using Swagger/OpenAPI that enables developers to understand, integrate, and test your API effectively.
Explanation
Section titled “Explanation”OpenAPI vs Swagger
Section titled “OpenAPI vs Swagger”OpenAPI: The specification standard (YAML/JSON format) describing REST APIs Swagger: A suite of tools built around the OpenAPI specification including:
- Swagger UI: Interactive documentation interface
- Swagger Editor: Create and edit OpenAPI specs
- Swagger Codegen: Generate client libraries
Key Components
Section titled “Key Components”- Paths: API endpoints
- Methods: HTTP verbs (GET, POST, PUT, DELETE)
- Parameters: Query, path, header, body parameters
- Responses: Status codes and response schemas
- Schemas: Data model definitions
- Security: Authentication and authorization schemes
Code Examples
Section titled “Code Examples”1. Basic Swagger Setup with Express
Section titled “1. Basic Swagger Setup with Express”const express = require('express');const swaggerJSDoc = require('swagger-jsdoc');const swaggerUI = require('swagger-ui-express');
const app = express();
const swaggerOptions = { definition: { openapi: '3.0.0', info: { title: 'My API', version: '1.0.0', description: 'API documentation', contact: { name: 'API Support', email: 'support@example.com', }, }, servers: [ { url: 'http://localhost:3000', description: 'Development server', }, { url: 'https://api.example.com', description: 'Production server', }, ], }, apis: ['./routes/*.js', './server.js'],};
const swaggerSpec = swaggerJSDoc(swaggerOptions);
app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerSpec));app.get('/api-docs.json', (req, res) => { res.json(swaggerSpec);});
app.listen(3000);2. Swagger Annotations in Routes
Section titled “2. Swagger Annotations in Routes”/** * @swagger * /api/users: * get: * summary: Get all users * description: Retrieve a list of all users * tags: * - Users * parameters: * - name: page * in: query * schema: * type: integer * default: 1 * - name: limit * in: query * schema: * type: integer * default: 10 * responses: * 200: * description: List of users * content: * application/json: * schema: * type: array * items: * $ref: '#/components/schemas/User' * 500: * description: Server error */app.get('/api/users', (req, res) => { res.json({ users: [] });});
/** * @swagger * /api/users/{id}: * get: * summary: Get user by ID * tags: * - Users * parameters: * - name: id * in: path * required: true * schema: * type: string * responses: * 200: * description: User details * content: * application/json: * schema: * $ref: '#/components/schemas/User' * 404: * description: User not found */app.get('/api/users/:id', (req, res) => { res.json({ id: req.params.id });});3. Swagger Components and Schemas
Section titled “3. Swagger Components and Schemas”const swaggerOptions = { definition: { openapi: '3.0.0', info: { title: 'My API', version: '1.0.0', }, components: { schemas: { User: { type: 'object', required: ['id', 'email'], properties: { id: { type: 'string', description: 'User ID', }, email: { type: 'string', format: 'email', description: 'User email', }, firstName: { type: 'string', }, lastName: { type: 'string', }, createdAt: { type: 'string', format: 'date-time', }, }, }, Error: { type: 'object', properties: { code: { type: 'integer', }, message: { type: 'string', }, }, }, }, securitySchemes: { bearerAuth: { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', }, }, }, }, apis: ['./routes/*.js'],};4. Swagger POST Endpoint
Section titled “4. Swagger POST Endpoint”/** * @swagger * /api/users: * post: * summary: Create a new user * tags: * - Users * security: * - bearerAuth: [] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: ['email', 'firstName'] * properties: * email: * type: string * format: email * firstName: * type: string * lastName: * type: string * responses: * 201: * description: User created successfully * content: * application/json: * schema: * $ref: '#/components/schemas/User' * 400: * description: Invalid input * 401: * description: Unauthorized */app.post('/api/users', authenticateToken, (req, res) => { const user = { id: '1', ...req.body }; res.status(201).json(user);});5. Swagger Tag Organization
Section titled “5. Swagger Tag Organization”const swaggerOptions = { definition: { openapi: '3.0.0', info: { title: 'My API', version: '1.0.0', }, tags: [ { name: 'Users', description: 'User management endpoints', }, { name: 'Products', description: 'Product management endpoints', }, { name: 'Orders', description: 'Order management endpoints', }, ], },};6. OpenAPI YAML Specification
Section titled “6. OpenAPI YAML Specification”openapi: 3.0.0info: title: My API version: 1.0.0 description: Complete API specificationservers: - url: http://localhost:3000 description: Development - url: https://api.example.com description: Production
paths: /api/users: get: tags: - Users summary: List all users parameters: - name: page in: query schema: type: integer responses: 200: description: Success content: application/json: schema: $ref: '#/components/schemas/UserList' post: tags: - Users summary: Create user requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' responses: 201: description: User created
components: schemas: User: type: object properties: id: type: string email: type: string name: type: stringBest Practices
Section titled “Best Practices”-
Keep Documentation Updated
- Update specs with code changes
- Use automated validation
- Version your API documentation
-
Provide Clear Examples
- Include request/response examples
- Show error responses
- Document edge cases
-
Use Consistent Naming
- Consistent parameter names
- Clear tag organization
- Descriptive operation IDs
-
Document Security
- Specify authentication methods
- List required permissions
- Document rate limiting
-
Test Your Documentation
- Use Swagger UI for manual testing
- Generate client libraries
- Validate specs programmatically
Real-World Applications
Section titled “Real-World Applications”- Public APIs: Communicate with external developers
- Internal APIs: Standardize communication between teams
- SDK Generation: Auto-generate client libraries
- Testing: Automated integration testing
- Contract Testing: Ensure API contracts are met