Menu
CoddyTech

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.

challenge icon

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.

  1. Trong src/tasks/dto/create-task.dto.ts, thêm hai trường vào lớp CreateTaskDto: title, kiểu chuỗi, và done, kiểu boolean không bắt buộc.
  2. Trong src/tasks/tasks.controller.ts, thay đổi phương thức create. Tham số @Body() của phương thức này giờ có kiểu CreateTaskDto thay vì { title: string }. Truyền toàn bộ DTO cho service, không chỉ riêng title.
  3. Trong src/tasks/tasks.service.ts, thay đổi create để nhận DTO thay vì title. Tác vụ mới lấy title từ DTO và cũng lấy done từ DTO, hoặc dùng false nếu nội dung không có done. id và createdAt vẫ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 {}
quiz iconTự kiểm tra

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