0
# SwaggerModule
1
2
The **SwaggerModule** class is the main integration point between NestJS applications and Swagger UI. It provides static methods for creating OpenAPI documents from your NestJS application metadata and setting up interactive Swagger UI documentation interfaces.
3
4
## Class Overview
5
6
```typescript { .api }
7
import { SwaggerModule } from '@nestjs/swagger';
8
9
class SwaggerModule {
10
static createDocument(
11
app: INestApplication,
12
config: Omit<OpenAPIObject, 'paths'>,
13
options?: SwaggerDocumentOptions
14
): OpenAPIObject;
15
16
static setup(
17
path: string,
18
app: INestApplication,
19
documentOrFactory: OpenAPIObject | (() => OpenAPIObject),
20
options?: SwaggerCustomOptions
21
): void;
22
23
static loadPluginMetadata(
24
metadataFn: () => Promise<Record<string, any>>
25
): Promise<void>;
26
}
27
```
28
29
## Document Creation
30
31
### createDocument { .api }
32
33
```typescript
34
static createDocument(
35
app: INestApplication,
36
config: Omit<OpenAPIObject, 'paths'>,
37
options?: SwaggerDocumentOptions
38
): OpenAPIObject
39
```
40
41
Creates a complete OpenAPI document by scanning the NestJS application for controllers, decorators, and metadata, then combining it with the provided configuration.
42
43
**Parameters:**
44
- `app`: The NestJS application instance
45
- `config`: OpenAPI document configuration (typically from DocumentBuilder)
46
- `options`: Optional document generation options
47
48
**Type Definitions:**
49
```typescript
50
interface SwaggerDocumentOptions {
51
include?: Function[];
52
extraModels?: Function[];
53
ignoreGlobalPrefix?: boolean;
54
deepScanRoutes?: boolean;
55
operationIdFactory?: OperationIdFactory;
56
linkNameFactory?: (controllerKey: string, methodKey: string, fieldKey: string) => string;
57
autoTagControllers?: boolean;
58
}
59
60
type OperationIdFactory = (
61
controllerKey: string,
62
methodKey: string,
63
version?: string
64
) => string;
65
```
66
67
**Basic Usage:**
68
```typescript
69
import { NestFactory } from '@nestjs/core';
70
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
71
import { AppModule } from './app.module';
72
73
async function bootstrap() {
74
const app = await NestFactory.create(AppModule);
75
76
const config = new DocumentBuilder()
77
.setTitle('My API')
78
.setDescription('API description')
79
.setVersion('1.0')
80
.build();
81
82
const document = SwaggerModule.createDocument(app, config);
83
84
// Document now contains all paths, schemas, and operations
85
console.log(document.paths); // All endpoint definitions
86
console.log(document.components); // All schema definitions
87
}
88
```
89
90
**Advanced Usage with Options:**
91
```typescript
92
import { ProductModule, UserModule } from './modules';
93
import { BaseDto, ErrorDto } from './common/dto';
94
95
const document = SwaggerModule.createDocument(app, config, {
96
// Only include specific modules
97
include: [ProductModule, UserModule],
98
99
// Add extra models that aren't automatically discovered
100
extraModels: [BaseDto, ErrorDto],
101
102
// Scan imported modules deeply
103
deepScanRoutes: true,
104
105
// Custom operation ID generation
106
operationIdFactory: (controllerKey, methodKey, version) => {
107
return `${controllerKey.toLowerCase()}_${methodKey}_v${version || '1'}`;
108
},
109
110
// Custom link name generation for OpenAPI links
111
linkNameFactory: (controllerKey, methodKey, fieldKey) => {
112
return `link_${controllerKey}_${methodKey}_${fieldKey}`;
113
},
114
115
// Disable automatic tag generation from controller names
116
autoTagControllers: false,
117
118
// Ignore global prefix for this documentation
119
ignoreGlobalPrefix: true
120
});
121
```
122
123
## Swagger UI Setup
124
125
### setup { .api }
126
127
```typescript
128
static setup(
129
path: string,
130
app: INestApplication,
131
documentOrFactory: OpenAPIObject | (() => OpenAPIObject),
132
options?: SwaggerCustomOptions
133
): void
134
```
135
136
Sets up Swagger UI at the specified path, serving both the interactive documentation interface and the raw OpenAPI specification in JSON/YAML formats.
137
138
**Parameters:**
139
- `path`: URL path where Swagger UI will be served
140
- `app`: The NestJS application instance
141
- `documentOrFactory`: OpenAPI document or factory function to generate it
142
- `options`: Extensive customization options for Swagger UI
143
144
**Type Definitions:**
145
```typescript
146
interface SwaggerCustomOptions {
147
useGlobalPrefix?: boolean;
148
ui?: boolean;
149
raw?: boolean | Array<'json' | 'yaml'>;
150
swaggerUrl?: string;
151
jsonDocumentUrl?: string;
152
yamlDocumentUrl?: string;
153
patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
154
req: TRequest,
155
res: TResponse,
156
document: OpenAPIObject
157
) => OpenAPIObject;
158
explorer?: boolean;
159
swaggerOptions?: SwaggerUiOptions;
160
customCss?: string;
161
customCssUrl?: string | string[];
162
customJs?: string | string[];
163
customJsStr?: string | string[];
164
customfavIcon?: string;
165
customSiteTitle?: string;
166
customSwaggerUiPath?: string;
167
}
168
```
169
170
**Basic Setup:**
171
```typescript
172
const config = new DocumentBuilder()
173
.setTitle('E-Commerce API')
174
.setVersion('1.0')
175
.build();
176
177
const document = SwaggerModule.createDocument(app, config);
178
179
// Serve Swagger UI at /api-docs
180
SwaggerModule.setup('api-docs', app, document);
181
182
// Now available at:
183
// http://localhost:3000/api-docs - Swagger UI interface
184
// http://localhost:3000/api-docs-json - JSON specification
185
// http://localhost:3000/api-docs-yaml - YAML specification
186
```
187
188
**Advanced Customization:**
189
```typescript
190
SwaggerModule.setup('api-docs', app, document, {
191
// Use global prefix if app.setGlobalPrefix() was called
192
useGlobalPrefix: true,
193
194
// Customize document URLs
195
jsonDocumentUrl: '/api/v1/spec.json',
196
yamlDocumentUrl: '/api/v1/spec.yaml',
197
198
// Enable OpenAPI definition selector in UI
199
explorer: true,
200
201
// Swagger UI customization
202
swaggerOptions: {
203
// Keep authorization when page refreshes
204
persistAuthorization: true,
205
// Display request duration
206
displayRequestDuration: true,
207
// Expand operations by default
208
docExpansion: 'list',
209
// Try it out enabled by default
210
tryItOutEnabled: true,
211
// Show/hide request examples
212
requestInterceptor: (req) => {
213
console.log('Request:', req);
214
return req;
215
}
216
},
217
218
// Custom styling
219
customSiteTitle: 'E-Commerce API Documentation',
220
customfavIcon: '/favicon.ico',
221
customCss: `
222
.topbar-wrapper { display: none; }
223
.swagger-ui .info { margin: 20px 0; }
224
`,
225
customCssUrl: [
226
'https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap'
227
],
228
229
// Dynamic document patching per request
230
patchDocumentOnRequest: (req, res, document) => {
231
// Add user-specific info or filter content based on request
232
const userRole = req.headers['x-user-role'];
233
234
if (userRole !== 'admin') {
235
// Remove admin-only paths
236
const filteredPaths = {};
237
Object.keys(document.paths).forEach(path => {
238
if (!path.includes('/admin/')) {
239
filteredPaths[path] = document.paths[path];
240
}
241
});
242
document.paths = filteredPaths;
243
}
244
245
return document;
246
}
247
});
248
```
249
250
**Document Factory Pattern:**
251
```typescript
252
// Use factory for dynamic document generation
253
SwaggerModule.setup('api-docs', app, () => {
254
const config = new DocumentBuilder()
255
.setTitle('Dynamic API')
256
.setVersion(process.env.API_VERSION || '1.0')
257
.setDescription(`Built at: ${new Date().toISOString()}`)
258
.build();
259
260
return SwaggerModule.createDocument(app, config);
261
}, {
262
customSiteTitle: 'Dynamic API Documentation'
263
});
264
```
265
266
## Selective Serving Options
267
268
### UI and Raw Document Control
269
270
```typescript
271
// Serve only Swagger UI (no raw JSON/YAML endpoints)
272
SwaggerModule.setup('docs', app, document, {
273
ui: true,
274
raw: false
275
});
276
277
// Serve only JSON specification (no UI or YAML)
278
SwaggerModule.setup('docs', app, document, {
279
ui: false,
280
raw: ['json']
281
});
282
283
// Serve UI and only YAML specification
284
SwaggerModule.setup('docs', app, document, {
285
ui: true,
286
raw: ['yaml']
287
});
288
289
// Disable everything (useful for conditional setup)
290
if (process.env.NODE_ENV !== 'production') {
291
SwaggerModule.setup('docs', app, document, {
292
ui: true,
293
raw: true
294
});
295
} else {
296
SwaggerModule.setup('docs', app, document, {
297
ui: false,
298
raw: false
299
});
300
}
301
```
302
303
## Plugin Metadata Loading
304
305
### loadPluginMetadata { .api }
306
307
```typescript
308
static loadPluginMetadata(
309
metadataFn: () => Promise<Record<string, any>>
310
): Promise<void>
311
```
312
313
Loads metadata from the Swagger TypeScript compiler plugin for enhanced automatic documentation generation.
314
315
**Usage:**
316
```typescript
317
// In your main.ts, before creating the document
318
await SwaggerModule.loadPluginMetadata(() =>
319
import('./swagger-plugin-metadata')
320
);
321
322
const document = SwaggerModule.createDocument(app, config);
323
SwaggerModule.setup('api', app, document);
324
```
325
326
## Complete Integration Examples
327
328
### Production-Ready Setup
329
330
```typescript
331
import { NestFactory } from '@nestjs/core';
332
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
333
import { AppModule } from './app.module';
334
335
async function bootstrap() {
336
const app = await NestFactory.create(AppModule);
337
338
// Set global prefix
339
app.setGlobalPrefix('api/v1');
340
341
// Load plugin metadata for enhanced documentation
342
if (process.env.NODE_ENV !== 'production') {
343
try {
344
await SwaggerModule.loadPluginMetadata(() =>
345
import('./swagger-plugin-metadata')
346
);
347
} catch (error) {
348
console.warn('Could not load Swagger plugin metadata:', error.message);
349
}
350
}
351
352
// Create comprehensive document configuration
353
const config = new DocumentBuilder()
354
.setTitle('E-Commerce Platform API')
355
.setDescription('Comprehensive e-commerce platform REST API')
356
.setVersion('2.0.0')
357
.setContact('API Team', 'https://example.com/contact', 'api@example.com')
358
.setLicense('MIT', 'https://opensource.org/licenses/MIT')
359
.addServer('https://api.example.com', 'Production')
360
.addServer('https://staging-api.example.com', 'Staging')
361
.addBearerAuth()
362
.addApiKey({ type: 'apiKey', in: 'header', name: 'X-API-Key' })
363
.addTag('Authentication', 'User authentication and authorization')
364
.addTag('Products', 'Product catalog management')
365
.addTag('Orders', 'Order processing and fulfillment')
366
.build();
367
368
// Generate document with advanced options
369
const document = SwaggerModule.createDocument(app, config, {
370
deepScanRoutes: true,
371
autoTagControllers: true,
372
operationIdFactory: (controllerKey, methodKey, version) =>
373
`${controllerKey}_${methodKey}${version ? `_v${version}` : ''}`,
374
});
375
376
// Setup with extensive customization
377
SwaggerModule.setup('docs', app, document, {
378
useGlobalPrefix: true,
379
explorer: true,
380
swaggerOptions: {
381
persistAuthorization: true,
382
displayRequestDuration: true,
383
filter: true,
384
showExtensions: true,
385
showCommonExtensions: true,
386
docExpansion: 'list'
387
},
388
customSiteTitle: 'E-Commerce API - Interactive Documentation',
389
customfavIcon: 'https://example.com/favicon.ico',
390
customCss: `
391
.swagger-ui .topbar { display: none; }
392
.swagger-ui .info .title { color: #1f2937; }
393
`,
394
customCssUrl: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600',
395
});
396
397
await app.listen(3000);
398
399
console.log(`Application is running on: ${await app.getUrl()}`);
400
console.log(`Swagger UI available at: ${await app.getUrl()}/api/v1/docs`);
401
}
402
403
bootstrap();
404
```
405
406
### Multi-Version API Setup
407
408
```typescript
409
async function setupMultiVersionDocs(app: INestApplication) {
410
// V1 API Documentation
411
const v1Config = new DocumentBuilder()
412
.setTitle('API v1')
413
.setVersion('1.0')
414
.addBearerAuth()
415
.build();
416
417
const v1Document = SwaggerModule.createDocument(app, v1Config, {
418
include: [V1Module],
419
ignoreGlobalPrefix: true
420
});
421
422
SwaggerModule.setup('docs/v1', app, v1Document);
423
424
// V2 API Documentation
425
const v2Config = new DocumentBuilder()
426
.setTitle('API v2')
427
.setVersion('2.0')
428
.addBearerAuth()
429
.addOAuth2()
430
.build();
431
432
const v2Document = SwaggerModule.createDocument(app, v2Config, {
433
include: [V2Module],
434
ignoreGlobalPrefix: true
435
});
436
437
SwaggerModule.setup('docs/v2', app, v2Document);
438
439
// Combined documentation with version selector
440
const combinedConfig = new DocumentBuilder()
441
.setTitle('Multi-Version API')
442
.setVersion('latest')
443
.addBearerAuth()
444
.build();
445
446
const combinedDocument = SwaggerModule.createDocument(app, combinedConfig, {
447
include: [V1Module, V2Module],
448
deepScanRoutes: true
449
});
450
451
SwaggerModule.setup('docs', app, combinedDocument, {
452
explorer: true,
453
swaggerOptions: {
454
urls: [
455
{ url: '/docs/v1-json', name: 'API v1' },
456
{ url: '/docs/v2-json', name: 'API v2' }
457
]
458
}
459
});
460
}
461
```
462
463
### Environment-Based Configuration
464
465
```typescript
466
function setupSwaggerBasedOnEnvironment(app: INestApplication, document: OpenAPIObject) {
467
const isDevelopment = process.env.NODE_ENV === 'development';
468
const isStaging = process.env.NODE_ENV === 'staging';
469
const isProduction = process.env.NODE_ENV === 'production';
470
471
if (isDevelopment) {
472
// Full-featured documentation for development
473
SwaggerModule.setup('api-docs', app, document, {
474
explorer: true,
475
swaggerOptions: {
476
persistAuthorization: true,
477
displayRequestDuration: true,
478
tryItOutEnabled: true
479
},
480
customSiteTitle: 'Dev API Documentation'
481
});
482
} else if (isStaging) {
483
// Limited documentation for staging
484
SwaggerModule.setup('docs', app, document, {
485
explorer: false,
486
swaggerOptions: {
487
tryItOutEnabled: false
488
},
489
customSiteTitle: 'Staging API Documentation'
490
});
491
} else if (isProduction) {
492
// Minimal or no documentation for production
493
if (process.env.ENABLE_DOCS === 'true') {
494
SwaggerModule.setup('internal-docs', app, document, {
495
ui: true,
496
raw: ['json'], // Only JSON, no YAML
497
swaggerOptions: {
498
tryItOutEnabled: false,
499
supportedSubmitMethods: [] // Disable try-it-out
500
},
501
customSiteTitle: 'Internal API Documentation'
502
});
503
}
504
// Otherwise, no Swagger setup in production
505
}
506
}
507
```
508
509
The SwaggerModule provides powerful, flexible integration between NestJS applications and Swagger UI, supporting everything from basic documentation needs to sophisticated multi-version, multi-environment setups with extensive customization options.