Menu
CoddyTech

DTO

Coddy Node.js 여정의 TypeScript와 NestJS 섹션에 포함된 레슨. 24개 중 13번째.

@Body() body: { title: string }는 한 곳에서만 본문을 설명할 뿐, 아무것도 이를 검사하지 않습니다. { "title": 42 }는 그대로 통과합니다. DTO, 즉 데이터 전송 객체는 요청 본문에 어떤 내용이 들어 있는지 설명하는 클래스입니다.

export class CreateOrderDto {
    customer: string;
    express?: boolean;
}

@Post()
create(@Body() dto: CreateOrderDto) {
    return this.ordersService.create(dto);
}

express?는 선택적 필드를 나타냅니다. 컨트롤러와 서비스가 같은 클래스를 사용하므로 데이터 구조에 대해 서로 일치합니다.

DTO가 인터페이스가 아니라 클래스인 데에는 이유가 있습니다. 코드가 실행될 때 인터페이스는 다른 타입과 함께 제거되지만, 클래스는 계속 남아 있습니다. Nest의 유효성 검사는 데코레이터로 작성된 규칙을 읽으며, 데코레이터에는 클래스가 필요합니다. 다음 강의에서 이를 다룹니다.

challenge icon

챌린지

쉬움

이제 클라이언트는 이미 완료된 작업을 만들 수 있습니다. 요청 본문에 포함되는 필드를 나열하는 클래스인 DTO로 POST /tasks의 본문을 설명하고, DTO를 서비스까지 전달하세요.

  1. src/tasks/dto/create-task.dto.ts에서 CreateTaskDto 클래스에 필드 두 개를 추가하세요. title은 문자열이고, done은 선택적 불리언입니다.
  2. src/tasks/tasks.controller.ts에서 create 메서드를 변경하세요. 이제 @Body() 매개변수의 타입은 { title: string }이 아니라 CreateTaskDto입니다. 제목만이 아니라 DTO 전체를 서비스에 전달하세요.
  3. src/tasks/tasks.service.ts에서 create가 제목 대신 DTO를 받도록 변경하세요. 새 작업의 title은 DTO에서 가져오고, done도 DTO에서 가져오거나 본문에 done이 없으면 false로 설정하세요. id와 createdAt은 이전과 같이 작동합니다.

직접 해보기: /tasks에 { "title": "Pay rent", "done": true }를 POST하세요. 201 응답과 완료된 새 작업을 받습니다.

{ "id": 4, "title": "Pay rent", "done": true, "createdAt": "2026-10-30T09:15:00.000Z" }

(createdAt에는 요청 시간이 표시됩니다.) { "title": "Buy milk" }를 POST하세요. "done": false와 함께 201 응답을 받습니다. 그런 다음 { "title": 42 }를 POST하세요. 여전히 201 응답을 받고, "title": 42가 저장됩니다. DTO는 본문을 설명하지만 아직 아무것도 검사하지 않습니다. 다음 강의에서는 Nest가 이 요청을 거부하도록 합니다.

직접 해보기

// POST /tasks의 본문을 설명합니다: 클라이언트가 보내는 경우 title과 done을 포함합니다.
export class CreateTaskDto {}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

TypeScript와 NestJS의 모든 레슨

직접 연습해 보세요: Express 플레이그라운드