Skip to content

DTO(Data Transfer Object,数据传输对象)

DTO(Data Transfer Object,数据传输对象) 是一种软件设计模式中的概念,主要用于在不同层或不同系统之间安全、高效地传输数据


🧩 核心目的

解耦 + 精简 + 安全

  • 避免直接暴露内部实体(Entity)或数据库模型;
  • 只传输需要的数据字段,减少网络负载;
  • 防止敏感信息(如密码、内部状态)被意外泄露;
  • 适配不同接口的返回格式需求。

📦 举个例子(以用户系统为例)

1. 数据库中的实体(Entity)

ts
// UserEntity(包含所有字段,甚至敏感信息)
class UserEntity {
  id: number;
  username: string;
  email: string;
  passwordHash: string;   // ❌ 敏感!不能直接返回给前端
  createdAt: Date;
  updatedAt: Date;
}

2. 前端需要的用户信息(DTO)

ts
// UserDTO(只包含安全、必要的字段)
interface UserDTO {
  id: number;
  username: string;
  email: string;          // ✅ 安全字段
  // 没有 passwordHash!
}

3. 在 API 中使用

ts
// Controller
app.get('/user/:id', (req, res) => {
  const user = userService.findById(req.params.id); // 返回 UserEntity
  const dto: UserDTO = {
    id: user.id,
    username: user.username,
    email: user.email
  };
  res.json(dto); // ✅ 只返回 DTO
});

🔁 DTO 的常见场景

场景说明
前后端通信后端返回给前端的数据结构(避免暴露 DB 字段)
微服务间调用服务 A 调用服务 B,通过 DTO 传递参数或结果
API 版本兼容v1 和 v2 接口返回不同 DTO,但底层 Entity 不变
请求参数校验使用 CreateUserDTO 接收前端提交的数据,并做验证

请求 DTO 示例(输入)

ts
// CreateUserDTO(用于接收注册请求)
interface CreateUserDTO {
  username: string;
  email: string;
  password: string; // 前端传明文,后端加密存储
}

✅ DTO 的优点

  1. 安全性:不暴露内部实现细节(如数据库主键策略、敏感字段);
  2. 灵活性:同一实体可对应多个 DTO(如 UserPublicDTOUserAdminDTO);
  3. 可维护性:修改数据库结构不影响 API 接口(只要 DTO 不变);
  4. 序列化友好:DTO 通常是 plain object,易于 JSON 转换。

⚠️ 注意事项

  • DTO 不应包含业务逻辑,它只是“数据容器”;
  • 不要为了 DTO 而过度设计——简单项目可直接用 Entity(但需谨慎);
  • 在 TypeScript/Java 等强类型语言中,DTO 通常定义为 interfaceclass(无方法)。

🌐 在不同技术栈中的体现

技术栈DTO 实践
NestJS(Node.js)使用 class-validator + class-transformer 定义 DTO
Spring Boot(Java)常见 UserDto.java,配合 @RequestBody / @ResponseBody
.NET使用 RecordClass 定义 DTO,配合 AutoMapper 映射
Vue/React 前端通常用 TypeScript interface 描述 API 返回的数据结构(这也是一种 DTO)

💡 一句话总结

DTO 就是你“愿意给别人看的数据样子”,而不是你“自己存的数据样子”。

如果你在写 API,建议始终通过 DTO 与外界交互,这是专业后端开发的常见实践 ✅。

Released under the MIT License.