Как настроить Swagger (OpenAPI) в NestJS?

MiddleNestJS · Backend·Обновлено 11 августа 2026
Коротко
Swagger в NestJS подключается через пакет @nestjs/swagger: устанавливается зависимость, в main.ts создаётся DocumentBuilder с метаданными API, затем SwaggerModule.createDocument и SwaggerModule.setup монтируют документацию по указанному URL.

Установка и базовая настройка

Для интеграции Swagger в NestJS используется официальный пакет @nestjs/swagger, который генерирует документацию на основе декораторов и TypeScript-типов.

npm install @nestjs/swagger

После установки настройка выполняется в 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('API платформы PurpleSchool')
    .setDescription('Документация REST API')
    .setVersion('1.0')
    .addBearerAuth() // добавляем JWT-авторизацию
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api/docs', app, document);

  await app.listen(3000);
}
bootstrap();

После запуска документация доступна по адресу http://localhost:3000/api/docs.

Аннотирование контроллеров и DTO

Swagger собирает описание из декораторов, расставленных на контроллерах и DTO-классах.

Контроллер

import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';

@ApiTags('Пользователи') // группировка в UI
@ApiBearerAuth()         // указывает, что роуты требуют JWT
@Controller('users')
export class UsersController {

  @Get(':id')
  @ApiOperation({ summary: 'Получить пользователя по ID' })
  @ApiResponse({ status: 200, description: 'Пользователь найден', type: UserDto })
  @ApiResponse({ status: 404, description: 'Пользователь не найден' })
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }
}

DTO-класс

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

export class CreateUserDto {
  @ApiProperty({ example: 'ivan@example.com', description: 'Email пользователя' })
  email: string;

  @ApiProperty({ example: 'секретный_пароль', minLength: 8 })
  password: string;

  @ApiPropertyOptional({ example: 'Иван', description: 'Имя пользователя' })
  name?: string;
}

Поддержка plugin для автоматической генерации

Chтобы не дублировать @ApiProperty над каждым полем, подключается CLI-плагин в nest-cli.json:

{
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}

Плагин автоматически считывает TypeScript-типы и JSDoc-комментарии, избавляя от необходимости явно указывать @ApiProperty для примитивных полей.

Схемы для Enum и вложенных объектов

import { ApiProperty } from '@nestjs/swagger';

export enum UserRole {
  Admin = 'admin',
  Student = 'student',
}

export class UserDto {
  @ApiProperty({ enum: UserRole, enumName: 'UserRole' })
  role: UserRole;

  @ApiProperty({ type: () => AddressDto }) // отложенный тип для вложенных объектов
  address: AddressDto;
}

Разделение документации по модулям (несколько документов)

Для крупных приложений можно создать несколько Swagger-документов с фильтрацией по тегам:

const adminDocument = SwaggerModule.createDocument(app, config, {
  include: [AdminModule], // только роуты AdminModule
});
SwaggerModule.setup('api/admin/docs', app, adminDocument);

Важные практики

  • Swagger UI в production рекомендуется отключать или защищать HTTP Basic Auth — документация раскрывает структуру API.
  • DocumentBuilder.addBearerAuth() нужно сочетать с @ApiBearerAuth() на контроллерах, иначе кнопка «Authorize» в UI не будет применяться к роутам.
  • Для корректного отображения массивов используйте @ApiProperty({ type: [ItemDto] }) или isArray: true.

Что хочет услышать интервьюер

Знание пакета @nestjs/swagger и процесса его подключения через DocumentBuilder + SwaggerModule

Понимание декораторов @ApiTags, @ApiOperation, @ApiResponse, @ApiProperty и их назначения

Осведомлённость о CLI-плагине для автоматической генерации метаданных из TypeScript-типов

Понимание необходимости защиты Swagger UI в production-окружении

Умение работать с авторизацией в Swagger: addBearerAuth / addApiKey и @ApiBearerAuth

Пример: Полная настройка Swagger в 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('PurpleSchool API')
    .setDescription('Документация REST API платформы')
    .setVersion('1.0')
    .addBearerAuth(
      { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' },
      'JWT-auth', // ключ, используемый в @ApiBearerAuth('JWT-auth')
    )
    .build();

  const document = SwaggerModule.createDocument(app, config);

  // отключаем Swagger в production
  if (process.env.NODE_ENV !== 'production') {
    SwaggerModule.setup('api/docs', app, document);
  }

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

Пример: Аннотированный контроллер и DTO

import { Controller, Post, Body, Get, Param } from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiProperty,
} from '@nestjs/swagger';

export class CreateCourseDto {
  @ApiProperty({ example: 'NestJS Pro', description: 'Название курса' })
  title: string;

  @ApiProperty({ example: 4999, description: 'Цена в рублях' })
  price: number;
}

export class CourseDto extends CreateCourseDto {
  @ApiProperty({ example: 1 })
  id: number;
}

@ApiTags('Курсы')
@ApiBearerAuth('JWT-auth')
@Controller('courses')
export class CoursesController {
  @Post()
  @ApiOperation({ summary: 'Создать курс' })
  @ApiResponse({ status: 201, type: CourseDto })
  create(@Body() dto: CreateCourseDto): CourseDto {
    return { id: 1, ...dto };
  }

  @Get(':id')
  @ApiOperation({ summary: 'Получить курс по ID' })
  @ApiResponse({ status: 200, type: CourseDto })
  @ApiResponse({ status: 404, description: 'Курс не найден' })
  findOne(@Param('id') id: string): CourseDto {
    return { id: +id, title: 'NestJS Pro', price: 4999 };
  }
}

Типичные ошибки

Забывают указать @ApiProperty на полях DTO и удивляются, что схема в UI пустая (без плагина аннотации обязательны)

Оставляют Swagger открытым в production без какой-либо защиты

Не используют enumName в @ApiProperty для enum — в схеме генерируются дублирующиеся безымянные enum-типы

Путают @ApiResponse (описание ответа) и @ApiBody (описание тела запроса) — @ApiBody нужен только для нестандартных тел, POST/PUT автоматически подхватывают DTO

Не подключают addBearerAuth() в DocumentBuilder, но расставляют @ApiBearerAuth() — кнопка Authorize в UI присутствует, но не работает

Лучшие курсы по теме

изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Node.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Nest.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее