DTOs
Thuộc phần TypeScript và NestJS trong hành trình Node.js của Coddy. Bài học 13 trên 24.
@Body() body: { title: string } mô tả phần thân ở một nơi duy nhất, và không có gì kiểm tra nó: { "title": 42 } được chuyển thẳng qua. DTO, viết tắt của đối tượng truyền dữ liệu, là một lớp mô tả nội dung của phần thân yêu cầu.
export class CreateOrderDto {
customer: string;
express?: boolean;
}
@Post()
create(@Body() dto: CreateOrderDto) {
return this.ordersService.create(dto);
}express? đánh dấu một trường không bắt buộc. Bộ điều khiển và dịch vụ dùng chung lớp này, nên chúng thống nhất về cấu trúc.
DTO là một lớp chứ không phải một interface, và có lý do cho điều đó. Interface bị loại bỏ cùng các kiểu khác khi code chạy, còn lớp vẫn tồn tại. Tính năng xác thực của Nest đọc các quy tắc được viết bằng decorator, mà decorator cần một lớp. Đó là nội dung của bài học tiếp theo.
Thử thách
DễGiờ đây, client có thể tạo một tác vụ đã hoàn thành. Mô tả nội dung của POST /tasks bằng DTO, một lớp liệt kê các trường trong nội dung yêu cầu, rồi truyền DTO đó đến tận service.
- Trong
src/tasks/dto/create-task.dto.ts, thêm hai trường vào lớpCreateTaskDto:title, kiểu chuỗi, vàdone, kiểu boolean không bắt buộc. - Trong
src/tasks/tasks.controller.ts, thay đổi phương thứccreate. Tham số@Body()của phương thức này giờ có kiểuCreateTaskDtothay vì{ title: string }. Truyền toàn bộ DTO cho service, không chỉ riêng title. - Trong
src/tasks/tasks.service.ts, thay đổicreateđể nhận DTO thay vì title. Tác vụ mới lấytitletừ DTO và cũng lấydonetừ DTO, hoặc dùngfalsenếu nội dung không códone. id vàcreatedAtvẫn hoạt động như trước.
Thử ngay: Gửi POST { "title": "Pay rent", "done": true } đến /tasks. Bạn nhận được mã 201 và tác vụ mới đã hoàn thành:
{ "id": 4, "title": "Pay rent", "done": true, "createdAt": "2026-10-30T09:15:00.000Z" }(createdAt hiển thị thời điểm bạn gửi yêu cầu.) Gửi POST { "title": "Buy milk" }: nhận mã 201 với "done": false. Sau đó, gửi POST { "title": 42 }. Bạn vẫn nhận được mã 201 và giá trị "title": 42 được lưu lại: DTO mô tả nội dung nhưng chưa kiểm tra gì cả. Bài học tiếp theo sẽ hướng dẫn Nest từ chối nội dung này.
Tự làm thử
// Mô tả phần thân của POST /tasks: gồm title và thuộc tính done nếu client gửi thuộc tính này.
export class CreateTaskDto {}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong TypeScript và NestJS
Tự luyện tập: Playground Express