🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 序列化(Serialization) 序列化(`Serialization`)是一个在网络响应中返回对象前的过程。 这是一个适合转换和净化要返回给客户的数据的地方。例如,应始终从最终响应中排除敏感数据(如用户密码)。此外,某些属性可能需要额外的转换,比方说,我们只想发送一个实体的子集。手动完成这些转换既枯燥又容易出错,并且不能确定是否覆盖了所有的情况。 > 译者注: `Serialization` 实现可类比 `composer` 库中 `fractal` ,响应给用户的数据不仅仅要剔除设计安全的属性,还需要剔除一些无用字段如 `create_time`, `delete_time`,` update_time` 和其他属性。在 `JAVA` 的实体类中定义 `N` 个属性的话就会返回 `N` 个字段,解决方法可以使用范型编程,否则操作实体类回影响数据库映射字段。 ### 概要 为了提供一种直接的方式来执行这些操作, `Nest` 附带了这个 `ClassSerializerInterceptor` 类。它使用[类转换器](https://github.com/typestack/class-transformer)来提供转换对象的声明性和可扩展方式。基于此类基础下,可以从类转换器中获取方法和调用 `classToPlain()` 函数返回的值。要这样做,可以将由`class-transformer`装饰器提供的规则应用在实体/DTO 类中,如下所示: ### 排除属性 我们假设要从一个用户实体中自动排除`password`属性。我们给实体做如下注释: ```typescript import { Exclude } from 'class-transformer'; export class UserEntity { id: number; firstName: string; lastName: string; @Exclude() password: string; constructor(partial: Partial<UserEntity>) { Object.assign(this, partial); } } ``` 然后,直接在控制器的方法中调用就能获得此类的实例。 ```typescript @UseInterceptors(ClassSerializerInterceptor) @Get() findOne(): UserEntity { return new UserEntity({ id: 1, firstName: 'Kamil', lastName: 'Mysliwiec', password: 'password', }); } ``` > 请注意,我们必须返回一个类的实体。如果你返回一个普通的 JavaScript 对象,例如,`{user: new UserEntity()}`,该对象将不会被正常序列化。 > 提示: `@ClassSerializerInterceptor()` 装饰器来源于 `@nestjs/common` 包。 现在当你调用此服务时,将收到以下响应结果: ```json { "id": 1, "firstName": "Kamil", "lastName": "Mysliwiec" } ``` 注意,拦截器可以应用于整个应用程序(见[这里](https://docs.nestjs.com/interceptors#binding-interceptors))。拦截器和实体类声明的组合确保返回 `UserEntity` 的任何方法都将确保删除 `password` 属性。这给你一个业务规则的强制、集中的评估。 ### 公开属性 您可以使用 `@Expose()` 装饰器来为属性提供别名,或者执行一个函数来计算属性值(类似于 `getter` 函数),如下所示。 ```typescript @Expose() get fullName(): string { return `${this.firstName} ${this.lastName}`; } ``` ### 变换 您可以使用 `@Transform()` 装饰器执行其他数据转换。例如,您要选择一个名称 `RoleEntity` 而不是返回整个对象。 ```typescript @Transform(role => role.name) role: RoleEntity; ``` ### 传递选项 你可能想要修改转换函数的默认行为。要覆盖默认设置,请使用 `@SerializeOptions()` 装饰器来将其传递给一个`options`对象。 ```typescript @SerializeOptions({ excludePrefixes: ['_'], }) @Get() findOne(): UserEntity { return {}; } ``` > 提示: `@SerializeOptions()` 装饰器来源于 `@nestjs/common` 包。 通过 `@SerializeOptions()` 传递的选项作为底层 `classToPlain()` 函数的第二个参数传递。在本例中,我们自动排除了所有以`_`前缀开头的属性。 ### Websockets 和 微服务 虽然本章展示了使用 `HTTP` 风格的应用程序的例子(例如,`Express` 或 `Fastify` ),但是 `ClassSerializerInterceptor`对于 `WebSockets` 和微服务的工作方式是一样的,不管使用的是哪种传输方法。 ### 了解更多 想了解有关装饰器选项的更多信息,请访问此[页面](https://github.com/typestack/class-transformer)。