nestjs-openapi-docs
npx skills add https://github.com/jacarrara/skills --skill nestjs-openapi-docs
Agent 安装分布
Skill 文档
NestJS OpenAPI Documentation
This skill provides step-by-step guidance for setting up and using OpenAPI (Swagger) documentation in NestJS applications.
Quick Start Workflow
Follow these steps based on your needs:
- First-time setup â Follow Initial Setup
- Document endpoints â See Documenting Endpoints
- Define DTOs/Models â See Defining Models
- Enable CLI plugin â See CLI Plugin Setup
- Advanced features â See references/advanced-features.md
Initial Setup
Installation
npm install --save @nestjs/swagger
Bootstrap Configuration
In main.ts:
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Cats example')
.setDescription('The cats API description')
.setVersion('1.0')
.addTag('cats')
.build();
const documentFactory = () => SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, documentFactory);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
Access Documentation
After starting the server (npm run start):
- Swagger UI:
http://localhost:3000/api - JSON spec:
http://localhost:3000/api-json
To customize JSON endpoint:
SwaggerModule.setup('api', app, documentFactory, {
jsonDocumentUrl: 'swagger/json',
});
// Access at: http://localhost:3000/swagger/json
Documenting Endpoints
Basic Controller Documentation
import { Controller, Get, Post, Body } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiCreatedResponse } from '@nestjs/swagger';
@ApiTags('cats')
@Controller('cats')
export class CatsController {
@Post()
@ApiOperation({ summary: 'Create a cat' })
@ApiCreatedResponse({
description: 'The cat has been successfully created.',
type: Cat,
})
async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
return this.catsService.create(createCatDto);
}
@Get()
@ApiOperation({ summary: 'Get all cats' })
@ApiOkResponse({
description: 'List of cats',
type: [Cat],
})
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
Response Decorators
Use short-hand decorators for common status codes:
@Post()
@ApiCreatedResponse({ description: 'Created successfully', type: Cat })
@ApiBadRequestResponse({ description: 'Invalid input' })
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
async create(@Body() createCatDto: CreateCatDto) {}
For full list of response decorators, see references/decorators.md.
Query Parameters
import { ApiQuery } from '@nestjs/swagger';
@Get()
@ApiQuery({ name: 'search', required: false, type: String })
@ApiQuery({ name: 'limit', required: false, type: Number })
async findAll(
@Query('search') search?: string,
@Query('limit') limit?: number,
) {}
Path Parameters
import { ApiParam } from '@nestjs/swagger';
@Get(':id')
@ApiParam({ name: 'id', type: 'string', description: 'Cat ID' })
async findOne(@Param('id') id: string) {}
Custom Headers
import { ApiHeader } from '@nestjs/swagger';
@Get()
@ApiHeader({
name: 'X-Custom-Header',
description: 'Custom header description',
})
async findAll() {}
Defining Models
Basic DTO
import { ApiProperty } from '@nestjs/swagger';
export class CreateCatDto {
@ApiProperty()
name: string;
@ApiProperty()
age: number;
@ApiProperty()
breed: string;
}
Optional Properties
@ApiPropertyOptional()
nickname?: string;
// Or
@ApiProperty({ required: false, default: 'Unknown' })
nickname?: string;
Property with Details
@ApiProperty({
description: 'The age of a cat',
minimum: 1,
maximum: 20,
default: 1,
example: 5,
})
age: number;
Arrays
@ApiProperty({ type: [String] })
tags: string[];
Enums
export enum CatBreed {
Persian = 'Persian',
Tabby = 'Tabby',
Siamese = 'Siamese',
}
@ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
breed: CatBreed;
For complex types, nested objects, polymorphic types, and raw definitions, see references/types-and-models.md.
CLI Plugin Setup
The CLI plugin automatically generates @ApiProperty() decorators, reducing boilerplate significantly.
Enable Plugin
Edit nest-cli.json:
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/swagger"]
}
}
With Options
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": [
{
"name": "@nestjs/swagger",
"options": {
"classValidatorShim": true,
"introspectComments": true
}
}
]
}
}
Before/After Plugin
Before (manual decorators):
export class CreateCatDto {
@ApiProperty()
name: string;
@ApiProperty()
age: number;
@ApiProperty({ required: false })
breed?: string;
}
After (with plugin):
export class CreateCatDto {
name: string;
age: number;
breed?: string;
}
Comment Introspection
With introspectComments: true:
/**
* A list of user's roles
* @example ['admin']
*/
roles: RoleEnum[] = [];
Equivalent to manually writing:
@ApiProperty({
description: `A list of user's roles`,
example: ['admin'],
})
roles: RoleEnum[] = [];
For detailed plugin configuration, SWC setup, and Jest integration, see references/cli-plugin.md.
File Upload Documentation
import { UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiConsumes, ApiBody } from '@nestjs/swagger';
class FileUploadDto {
@ApiProperty({ type: 'string', format: 'binary' })
file: any;
}
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
description: 'File upload',
type: FileUploadDto,
})
uploadFile(@UploadedFile() file: Express.Multer.File) {}
Authentication Documentation
Bearer Token
// In controller
@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
// In bootstrap
const config = new DocumentBuilder()
.addBearerAuth()
.build();
Basic Auth
// In controller
@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
// In bootstrap
const config = new DocumentBuilder()
.addBasicAuth()
.build();
For OAuth2, Cookie auth, and custom security schemes, see references/advanced-features.md.
Common Issues
Fastify + Helmet CSP Conflict
When using Fastify with Helmet:
app.register(helmet, {
contentSecurityPolicy: {
directives: {
defaultSrc: [`'self'`],
styleSrc: [`'self'`, `'unsafe-inline'`],
imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
},
},
});
Plugin Not Working
- Delete
/distfolder - Restart the application
- Ensure files have
.dto.tsor.entity.tssuffix - Check
nest-cli.jsonconfiguration
Missing Models in Swagger
Add extra models explicitly:
@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
// Or in document options
const documentFactory = () =>
SwaggerModule.createDocument(app, options, {
extraModels: [ExtraModel],
});
Reference Files
Detailed documentation for specific features:
- decorators.md – Complete list of all OpenAPI decorators with examples
- types-and-models.md – Complex types, generics, polymorphic models, raw definitions
- cli-plugin.md – Plugin configuration, SWC setup, Jest integration
- advanced-features.md – Mapped types, security, multiple specs, global config
Example
A working example is available at: https://github.com/nestjs/nest/tree/master/sample/11-swagger