Tự động tạo tài liệu API bằng OpenAPI & Scalar
Tài liệu API (API Documentation) là thành phần không thể thiếu khi phát triển Backend. Nó giúp các lập trình viên Frontend, Mobile hoặc đối tác tích hợp hiểu rõ cách tương tác với hệ thống của bạn mà không cần đọc trực tiếp mã nguồn. Thay vì viết tài liệu thủ công hoặc sử dụng giao diện Swagger UI truyền thống đã lỗi thời, chúng ta sẽ kết hợp OpenAPI (Swagger) của NestJS với Scalar – một giao diện tài liệu API hiện đại, trực quan, hỗ trợ thử nghiệm trực tiếp (Request Client) và tự động sinh mã code tích hợp cho nhiều ngôn ngữ khác nhau.1. Cài đặt thư viện cần thiết
Để bắt đầu, bạn cần cài đặt bộ thư viện tạo OpenAPI của NestJS cùng với middleware giao diện của Scalar:2. Cấu hình tài liệu API trong tệp khởi động
Sau khi cài đặt xong, bạn hãy cấu hình tài liệu API trong tệp khởi độngsrc/main.ts của ứng dụng:
src/main.ts
3. Các tình huống gán Decorator phổ biến trong dự án
Để đặc tả chi tiết các trường thông tin trong DTO và các endpoint trong Controller, NestJS cung cấp một bộ các decorator tương ứng theo từng tình huống nghiệp vụ:A. Tình huống mô tả thuộc tính trong DTO
Khi Client gửi dữ liệu lên, bạn cần mô tả rõ kiểu dữ liệu, ý nghĩa và ví dụ mẫu của từng trường thông tin.@ApiProperty(): Khai báo thuộc tính bắt buộc.@ApiPropertyOptional(): Khai báo thuộc tính không bắt buộc (tương đương@ApiProperty({ required: false })).
Các tham số cấu hình chính trong @ApiProperty:
| Tham số | Ý nghĩa | Ví dụ |
|---|---|---|
description | Mô tả ý nghĩa của trường dữ liệu. | description: 'Tên đăng nhập' |
example | Ví dụ dữ liệu thực tế giúp sinh tài liệu trực quan. | example: 'john_doe' |
type | Kiểu dữ liệu (nếu là đối tượng lồng nhau hoặc không tự nhận diện). | type: () => UserProfile |
enum | Danh sách các giá trị được chấp nhận. | enum: ['ACTIVE', 'INACTIVE'] |
isArray | Xác định trường này là một mảng. | isArray: true |
src/users/dto/create-user-profile.dto.ts
B. Tình huống gom nhóm và đặt tên Endpoint (Controller)
@ApiTags('tên_nhóm'): Gom nhóm các API liên quan vào một thư mục trên giao diện tài liệu giúp dễ tìm kiếm (thường đặt ở cấp Class của Controller).@ApiOperation({ summary, description }): Mô tả ngắn gọn tính năng của endpoint (summary) và ghi chú chi tiết logic xử lý bên trong nếu cần (description).
src/users/users.controller.ts
C. Tình huống nhận tham số từ URL (Route Params & Query String)
Khi endpoint cần nhận các tham số lọc hoặc tìm kiếm, bạn cần ghi chú rõ ràng để kiểm thử trực tiếp trên giao diện.@ApiParam(): Đặc tả tham số động trên URL đường dẫn (ví dụ::id,:code).@ApiQuery(): Đặc tả các tham số lọc gửi sau dấu chấm hỏi (ví dụ:?page=1&limit=10).
D. Tình huống định nghĩa kết quả trả về (Responses)
Ghi chú đầy đủ các mã trạng thái phản hồi HTTP giúp phía Client xử lý chính xác các trường hợp thành công hoặc lỗi:@ApiResponse(): Đặc tả phản hồi tổng quát bằng cách chỉ định mã sốstatus.- Các decorator chuyên biệt (khuyên dùng):
@ApiOkResponse({ description, type }): Phản hồi thành công với mã 200 (thường cho GET, PUT, PATCH, DELETE).@ApiCreatedResponse({ description, type }): Phản hồi thành công với mã 201 (thường cho POST).@ApiBadRequestResponse({ description }): Lỗi dữ liệu đầu vào không hợp lệ (mã 400).@ApiUnauthorizedResponse({ description }): Lỗi chưa xác thực thông tin đăng nhập (mã 401).@ApiNotFoundResponse({ description }): Lỗi không tìm thấy tài nguyên (mã 404).
E. Tình huống yêu cầu bảo mật (Xác thực JWT Token)
Nếu API yêu cầu phải gửi Token trong Header để truy cập, bạn cần đánh dấu bảo mật để giao diện Scalar hiển thị nút nhập token và tự động đính kèm vào các lượt gọi thử nghiệm.@ApiBearerAuth(): Khai báo endpoint yêu cầu xác thực dạng Bearer Token (JWT).- Lưu ý: Phải gọi
.addBearerAuth()trongmain.tstrước.
- Lưu ý: Phải gọi
F. Tình huống tải lên tập tin (File Upload)
Đối với các API tải ảnh hoặc tập tin (avatar, tài liệu), bạn cần định cấu hình kiểu truyền tải làmultipart/form-data và ghi chú rõ trường nhận file.
@ApiConsumes('multipart/form-data'): Khai báo API nhận dữ liệu dạng form-data chứa tập tin.@ApiBody(): Đặc tả trực tiếp cấu trúc body nhận tập tin nhị phân.
4. Cách phối hợp viết OpenAPI với Claude Code
Việc gán thủ công từng decorator cho tất cả DTO và Controller có thể tốn nhiều thời gian. Bạn có thể sử dụng Claude Code để tự động hóa hoàn toàn quy trình này thông qua các prompt hướng dẫn chi tiết.Prompt mẫu bổ sung OpenAPI:
5. Xem và kiểm thử API trên trình duyệt
- Khởi động ứng dụng NestJS của bạn:
- Mở trình duyệt và truy cập đường dẫn:
http://localhost:3000/reference - Tại giao diện Scalar, bạn có thể:
- Xem toàn bộ cấu trúc các DTO dưới dạng tài liệu mô tả chi tiết.
- Click chọn mục Test Request để gửi trực tiếp yêu cầu HTTP đến Backend và kiểm tra kết quả phản hồi.
- Chọn mục Code Snippets để sao chép mã nguồn gọi API tương ứng bằng JavaScript, Python, Go, Curl, v.v.