nestjs-openapi-docs

📁 jacarrara/skills 📅 10 days ago
1
总安装量
1
周安装量
#44276
全站排名
安装命令
npx skills add https://github.com/jacarrara/skills --skill nestjs-openapi-docs

Agent 安装分布

claude-code 1

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:

  1. First-time setup → Follow Initial Setup
  2. Document endpoints → See Documenting Endpoints
  3. Define DTOs/Models → See Defining Models
  4. Enable CLI plugin → See CLI Plugin Setup
  5. 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

  1. Delete /dist folder
  2. Restart the application
  3. Ensure files have .dto.ts or .entity.ts suffix
  4. Check nest-cli.json configuration

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:

Example

A working example is available at: https://github.com/nestjs/nest/tree/master/sample/11-swagger