DTOs (Data Transfer Objects)

A DTO is a class that defines the shape of data coming into or out of your API.

Syntaxexport class CreateUserDto { ... }

A DTO (Data Transfer Object) describes the shape of data moving between the client and your app. In Nest, DTOs are classes rather than interfaces.

Why a class, not an interface?

Interfaces disappear at runtime because they are a TypeScript-only concept. Classes remain, so Nest can attach validation rules and use them with pipes. This is why DTOs are the foundation of request validation.

Name them by intent, such as CreateUserDto and UpdateUserDto.

Example

Example · typescript
// dto/create-user.dto.ts
export class CreateUserDto {
  name: string;
  email: string;
  age: number;
}

// users.controller.ts
@Post()
create(@Body() dto: CreateUserDto) {
  return `creating ${dto.name}`;
}

When to use it

  • A developer creates a CreateUserDto with @IsEmail and @MinLength decorators so the API rejects malformed user payloads before they reach the service.
  • A team uses separate CreateProductDto and UpdateProductDto classes so partial updates do not require all fields.
  • An architect uses DTOs as a contract between the HTTP layer and the service layer, preventing raw request objects from leaking into business logic.

More examples

Basic DTO class

Defines a plain DTO class that shapes incoming POST /users body data without any validation decorators yet.

Example · ts
export class CreateUserDto {
  name: string;
  email: string;
  age: number;
}

DTO with class-validator decorators

Adds validation decorators so the global ValidationPipe rejects requests that violate the rules before the handler runs.

Example · ts
import { IsEmail, IsString, MinLength, IsInt, Min } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @MinLength(2)
  name: string;

  @IsEmail()
  email: string;

  @IsInt()
  @Min(0)
  age: number;
}

UpdateDto extending CreateDto

Uses PartialType to make all fields of CreateUserDto optional in UpdateUserDto, following the DRY principle for PATCH routes.

Example · ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateUserDto } from './create-user.dto';

export class UpdateUserDto extends PartialType(CreateUserDto) {}

Discussion

  • Be the first to comment on this lesson.