Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Документация 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 не читает: правила проверки и описание для документации — разные вещи, и нужны оба.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.