Документация API: Swagger
OpenAPI — стандарт описания HTTP API: какие есть адреса, что они принимают и возвращают. Swagger UI — веб-страница, которая показывает такое описание и позволяет отправлять запросы прямо из браузера. Пакет @nestjs/swagger строит описание по вашим контроллерам и DTO, так что документацию не нужно писать отдельно.
Установка и подключение
npm i @nestjs/swagger// src/main.ts
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Blog API')
.setDescription('Статьи, комментарии и пользователи')
.setVersion('1.0')
.addBearerAuth()
.build();
const documentFactory = () => SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, documentFactory);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();DocumentBuilder задаёт заголовок и версию, addBearerAuth() добавляет поле для токена JWT. Откройте http://localhost:3000/docs — появится страница со списком всех маршрутов. Описание в формате JSON лежит по адресу /docs-json.
Описание полей DTO
Swagger видит маршруты, но не знает, какие поля в DTO: типы TypeScript исчезают при компиляции. Поля описывают декоратором @ApiProperty():
// src/posts/dto/create-post.dto.ts
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
export class CreatePostDto {
@ApiProperty({ example: 'Привет, Nest', maxLength: 120 })
@IsString()
@IsNotEmpty()
@MaxLength(120)
title: string;
@ApiProperty({ example: 'Текст первой статьи' })
@IsString()
@IsNotEmpty()
content: string;
}Теперь в документации у POST /posts появится пример тела запроса. Необязательные поля помечают @ApiPropertyOptional().
В UpdatePostDto замените импорт PartialType на import { PartialType } from '@nestjs/swagger' — эта версия переносит и описания полей.
Группы и защита
// src/posts/posts.controller.ts
import { Controller } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
@ApiTags('posts')
@ApiBearerAuth()
@Controller('posts')
export class PostsController {}@ApiTags() собирает маршруты в группу на странице, @ApiBearerAuth() показывает, что для них нужен токен. Нажмите кнопку Authorize вверху страницы, вставьте токен — и запросы из документации будут отправляться с ним.
Полезные декораторы
| Декоратор | Что описывает |
|---|---|
@ApiProperty() | Поле DTO или сущности |
@ApiTags('posts') | Группу маршрутов |
@ApiBearerAuth() | Нужен токен JWT |
@ApiOperation({ summary: '...' }) | Краткое описание маршрута |
@ApiResponse({ status: 404 }) | Возможный ответ |
Чтобы не писать @ApiProperty() у каждого поля, можно включить плагин CLI: в nest-cli.json в раздел compilerOptions добавляют "plugins": ["@nestjs/swagger"], и он описывает поля по типам TypeScript сам.
Частая ошибка
Документация показывает пустую схему тела запроса, хотя DTO есть. Причина — у полей нет @ApiProperty() и плагин не включён. Декораторы class-validator Swagger не читает: правила проверки и описание для документации — разные вещи, и нужны оба.