Swagger System
The template provides a complete Swagger/OpenAPI documentation system built on swagger-jsdoc. It includes annotation helpers in lib/swagger/annotations.ts for standardizing API documentation across all route handlers.
Architecture
Annotation Type System
The lib/swagger/annotations.ts module defines TypeScript interfaces that mirror the OpenAPI 3.0 specification:
SwaggerRouteConfig
The main configuration object for documenting an API route:
interface SwaggerRouteConfig {
tags: string[]; // API grouping tags
summary: string; // Brief description
description: string; // Detailed description
security?: Array<Record<string, string[]>>; // Security requirements
parameters?: SwaggerParameter[]; // Query/path/header params
requestBody?: SwaggerRequestBody; // Request body schema
responses: Record<string, SwaggerResponse>; // Response definitions
}
SwaggerParameter
Defines query, path, or header parameters:
interface SwaggerParameter {
name: string;
in: 'query' | 'path' | 'header';
required?: boolean;
schema: {
type: string;
format?: string;
minimum?: number;
maximum?: number;
default?: any;
enum?: string[];
};
description?: string;
example?: any;
}
SwaggerRequestBody
Defines the request body structure:
interface SwaggerRequestBody {
required: boolean;
content: {
'application/json': {
schema: {
$ref?: string; // Reference to a component schema
type?: string; // Inline type definition
properties?: Record<string, any>;
};
example?: any;
};
};
}
SwaggerResponse
Defines response status codes and their schemas:
interface SwaggerResponse {
description: string;
content?: {
'application/json': {
schema: {
$ref?: string;
type?: string;
properties?: Record<string, any>;
};
example?: any;
examples?: Record<string, any>;
};
};
}
Common Annotations
The CommonAnnotations object provides reusable building blocks:
Standard Error Responses
CommonAnnotations.responses.unauthorized
// { description: 'Authentication required', ... }
CommonAnnotations.responses.forbidden
// { description: 'Forbidden - Admin access required', ... }
CommonAnnotations.responses.notFound
// { description: 'Resource not found', ... }
CommonAnnotations.responses.serverError
// { description: 'Internal server error', ... }
Each error response includes a standard example:
{
"success": false,
"error": "Error message"
}
Pagination Parameters
CommonAnnotations.paginationParameters
// [
// { name: 'page', in: 'query', schema: { type: 'integer', minimum: 1, default: 1 } },
// { name: 'limit', in: 'query', schema: { type: 'integer', minimum: 1, maximum: 100, default: 10 } }
// ]
Admin Security
CommonAnnotations.adminSecurity
// [{ sessionAuth: [] }]
Creating Annotations
createSwaggerAnnotation()
Generates a complete @swagger JSDoc comment string:
import { createSwaggerAnnotation, CommonAnnotations } from '@/lib/swagger/annotations';
const annotation = createSwaggerAnnotation('/api/items', 'GET', {
tags: ['Items'],
summary: 'List all items',
description: 'Returns a paginated list of items with filtering support',
parameters: [
...CommonAnnotations.paginationParameters,
{
name: 'category',
in: 'query',
required: false,
schema: { type: 'string' },
description: 'Filter by category',
example: 'Web Development'
}
],
responses: {
'200': {
description: 'Paginated list of items',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Pagination' },
example: {
items: [{ id: '1', title: 'Sample Item' }],
pagination: { page: 1, pageSize: 10, total: 50, totalPages: 5 }
}
}
}
},
'500': CommonAnnotations.responses.serverError
}
});
createAdminRouteAnnotation()
Shorthand for admin-protected routes. Automatically adds sessionAuth security:
import { createAdminRouteAnnotation, CommonAnnotations } from '@/lib/swagger/annotations';
const annotation = createAdminRouteAnnotation('/api/admin/users', 'GET', {
tags: ['Admin'],
summary: 'List all users',
description: 'Returns all registered users with their profiles and roles',
parameters: CommonAnnotations.paginationParameters,
responses: {
'200': {
description: 'User list with pagination',
content: {
'application/json': {
schema: { type: 'object' },
example: {
items: [{ id: '1', email: 'admin@example.com', role: 'admin' }],
pagination: { page: 1, pageSize: 10, total: 100, totalPages: 10 }
}
}
}
},
'401': CommonAnnotations.responses.unauthorized,
'403': CommonAnnotations.responses.forbidden,
'500': CommonAnnotations.responses.serverError
}
});
Writing Route Documentation
Direct Annotation Pattern
The most common approach is writing @swagger comments directly in route files:
// app/api/items/route.ts
/**
* @swagger
* /api/items:
* get:
* tags: ["Items"]
* summary: "Get all items"
* description: "Returns paginated items list with optional category filter"
* parameters:
* - name: "page"
* in: query
* schema:
* type: integer
* default: 1
* - name: "limit"
* in: query
* schema:
* type: integer
* default: 10
* responses:
* 200:
* description: "Success"
* 500:
* description: "Server error"
*/
export async function GET(request: Request) {
// implementation
}
POST Route with Request Body
/**
* @swagger
* /api/items:
* post:
* tags: ["Items"]
* summary: "Create a new item"
* security:
* - sessionAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* title:
* type: string
* description:
* type: string
* category:
* type: string
* example:
* title: "My New Item"
* description: "Item description"
* category: "Web Development"
* responses:
* 201:
* description: "Item created"
* 400:
* description: "Validation error"
* 401:
* description: "Unauthorized"
*/
export async function POST(request: Request) {
// implementation
}
Tag Organization
Organize API routes into logical groups using tags:
| Tag | Routes | Description |
|---|---|---|
Items | /api/items/* | Public item listing and details |
Admin | /api/admin/* | Admin dashboard operations |
Auth | /api/auth/* | Authentication flows |
Profile | /api/profile/* | User profile management |
Newsletter | /api/newsletter/* | Newsletter subscriptions |
Comments | /api/comments/* | Comment CRUD operations |
Payments | /api/payments/* | Payment processing |
Cron | /api/cron/* | Scheduled job endpoints |
Security Schemes
Three security schemes are defined in the OpenAPI configuration:
Usage in Annotations
# JWT Bearer authentication
security:
- sessionAuth: []
# Cookie-based session
security:
- session: []
# Cron job secret
security:
- cronSecret: []
Generated Output
The generate-openapi.ts script produces public/openapi.json with this structure:
{
"openapi": "3.0.0",
"info": { "title": "Ever Works API", "version": "1.0.0" },
"servers": [{ "url": "/" }],
"paths": {
"/api/items": { "get": { ... }, "post": { ... } },
"/api/admin/users": { "get": { ... } }
},
"components": {
"securitySchemes": { ... },
"schemas": {
"ErrorResponse": { ... },
"PaginationMeta": { ... },
"Pagination": { ... }
}
},
"tags": [
{ "name": "Items" },
{ "name": "Admin" }
]
}
Best Practices
- Document every public route -- All routes in
app/api/should have@swaggerannotations - Use
$reffor shared schemas -- Reference component schemas instead of duplicating definitions - Include examples -- Always provide
examplevalues for request and response bodies - Use CommonAnnotations -- Leverage the shared error responses and pagination parameters
- Tag consistently -- Group related endpoints under the same tag name
- Describe parameters -- Include
descriptionandexamplefor every parameter - Document all status codes -- Cover success, validation error, auth error, and server error cases
- Keep annotations close to handlers -- Place
@swaggercomments directly above the route handler function