API Documentation with Swagger
ជំពូកនេះមិនទាន់ត្រូវបានបកប្រែជាភាសាខ្មែរនៅឡើយទេ — សូមអានជាភាសាអង់គ្លេសខាងក្រោម។
Table of Contents
- Why Swagger / OpenAPI
- Installing and Configuring Swagger
- Documenting the DTOs
- Documenting the Controller
- Trying It in the Browser
- Beginner Pitfalls
1. Why Swagger / OpenAPI
So far, trying any route meant writing a curl command by hand. Swagger
UI generates an interactive, browsable page listing every route, its
expected request body, and its possible responses — and lets you send
real requests straight from the browser. NestJS generates this
automatically from the same decorators already on your controllers and
DTOs.
2. Installing and Configuring Swagger
npm install @nestjs/swagger
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
const config = new DocumentBuilder()
.setTitle('Task Management API')
.setDescription('A small task-management REST API built in the NestJS crash course')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
SwaggerModule.setup('api', app, document) serves the UI at
/api.
3. Documenting the DTOs
@ApiProperty() describes each field for the generated docs — Swagger
can't infer descriptions or examples from class-validator decorators
alone:
// src/tasks/dto/create-task.dto.ts
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator';
export class CreateTaskDto {
@ApiProperty({ example: 'Learn NestJS' })
@IsString()
@IsNotEmpty()
title: string;
@ApiPropertyOptional({ example: 'Build my first API' })
@IsOptional()
@IsString()
description?: string;
@ApiPropertyOptional({ default: false })
@IsOptional()
@IsBoolean()
done?: boolean;
}
UpdateTaskDto (from Part 5)
already reuses these via PartialType — no changes needed there;
@nestjs/swagger's PartialType (a drop-in replacement for the one from
@nestjs/mapped-types) carries the @ApiProperty() metadata through
automatically.
4. Documenting the Controller
// src/tasks/tasks.controller.ts (excerpt)
import { ApiOperation, ApiTags } from '@nestjs/swagger';
@ApiTags('tasks')
@Controller('tasks')
export class TasksController {
constructor(private readonly tasksService: TasksService) {}
@ApiOperation({ summary: 'List all tasks' })
@Get()
findAll() {
return this.tasksService.findAll();
}
// ...same pattern for the other four routes
}
@ApiTags('tasks') groups every route in this controller under one
"tasks" section in the UI; @ApiOperation() adds a one-line summary per
route.
5. Trying It in the Browser
With npm run start:dev running, open http://localhost:3000/api. You
should see all five /tasks routes, grouped under "tasks", each
expandable with a "Try it out" button — fill in a request body and send a
real POST or PATCH without leaving the browser.
6. Beginner Pitfalls
- Forgetting
@nestjs/swagger'sPartialType. IfUpdateTaskDtostill importsPartialTypefrom@nestjs/mapped-types(as in Part 5), it still works — but switching to@nestjs/swagger's version is what carries the@ApiProperty()metadata into the generated docs forPATCH. - Exposing
/apiin production without thinking about it. Swagger UI reveals your entire API surface — gate it behind an environment check (if (!isProduction) SwaggerModule.setup(...)) or auth before deploying publicly. - Letting docs drift from the code. Because Swagger reads the same decorators the app runs on, docs and behavior can't drift apart the way a hand-written docs page can — but only if you keep the decorators updated when a route's actual behavior changes.
Official docs:
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!