DTO(数据传输对象) 是一个类,它定义了发送到 API 或从 API 返回的数据的 形状 — 通常是请求体的结构。DTO 提供类型安全、充当端点的明确契约,并且(通过验证装饰器)启用自动输入验证。
定义 DTO
ts
{ , , , , , } ;
{
()
: ;
()
()
: ;
()
()
()
?: ;
}
DTO 是描述预期数据的普通类,带有 验证装饰器(来自 class-validator),指定每个字段必须满足的规则。
@Post()
create(@Body() dto: CreateUserDto) { // the body is typed AND validated as CreateUserDto
// dto is guaranteed to be valid here (with the validation pipe enabled)
return this.usersService.create(dto);
}
@Body() dto: CreateUserDto 为请求体进行类型标注,并且 — 启用验证管道后 — 在你的处理器运行之前自动验证它。
// main.ts — turn on the global validation pipe
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // strip properties NOT in the DTO (security)
forbidNonWhitelisted: true, // reject requests with extra unknown properties
transform: true, // auto-transform payloads to DTO instances + convert types
}));
通过 ValidationPipe,NestJS 自动根据 DTO 的装饰器验证传入的请求体 — 如果验证失败,会返回 400 错误并提供详情,这发生在你的代码运行之前。
DTO → the shape of data crossing the API boundary (request/response contract)
Entity → the database model (e.g. a TypeORM entity / Prisma model)
→ Keep them SEPARATE: the API contract shouldn't be coupled to the DB schema.
(A CreateUserDto has password+email; the User entity has id, timestamps, etc.)
DTO 刻意与数据库实体不同 — 它们表示 API 接受/返回的内容,与内部存储解耦。
import { PartialType } from "@nestjs/mapped-types";
// derive an UpdateUserDto where all fields are optional — no duplication
export class UpdateUserDto extends PartialType(CreateUserDto) {}
DTO 是一个重要的 NestJS 模式,为你的端点带来类型安全、清晰的 API 契约和自动验证。
它们精确定义了端点接受的数据(请求形状),为你提供编译时类型检查并充当自文档化的契约。
至关重要的是,结合 class-validator 装饰器和 ValidationPipe,它们启用了 自动输入验证 — 格式错误或恶意的请求在 到达 你的业务逻辑之前就被拒绝并返回清晰的错误,这对安全性和健壮性至关重要(whitelist 选项也会剥离意外的属性)。
理解 DTO、如何添加验证规则、如何启用验证管道,以及 将 DTO 与数据库实体分离 的重要原则(将 API 契约与内部存储解耦)是构建安全、结构良好、可维护的 NestJS API 的基础。
DTO 出现在几乎每个接受输入的端点中,使其成为日常必不可少的知识。