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