📜  nestjs mongoose ClassSerializerInterceptor 不起作用 - Javascript (1)

📅  最后修改于: 2023-12-03 15:17:51.144000             🧑  作者: Mango

NestJS Mongoose ClassSerializerInterceptor 不起作用 - Javascript

最近在开发 NestJS 应用的过程中,遇到了一个问题: ClassSerializerInterceptor 在使用 Mongoose 时似乎不起作用。

什么是 ClassSerializerInterceptor?

ClassSerializerInterceptor 是 NestJS 框架中的一个拦截器,用于将返回给客户端的数据对象进行序列化。通常情况下,客户端不需要看到数据对象中的所有属性,而是只需要一部分。

ClassSerializerInterceptor 可以通过排除一些属性或者仅包含一些属性来达到实现数据显示控制的效果。

为什么在 Mongoose 中不起作用?

经过研究后发现,Mongoose 的文档是以方法的形式来封装数据对象的,例如:

const schema = new mongoose.Schema({ name: String });
const Cat = mongoose.model('Cat', schema);
const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));

在 NestJS 的 Controller 中,我们可以这样返回 Mongoose 的文档:

@Get()
findAll(): Promise<Cat[]> {
  return this.catsService.findAll();
}

返回的是一个 Cat 类型的数组。

但是实际上,这个数组中的每个元素并不是一个简单的 JavaScript 对象,而是一个被 Mongoose 封装的文档对象。而这个文档对象的属性并不是通过定义在类中的字段来定义的,而是被 Mongoose 在运行时动态添加的。

因此,ClassSerializerInterceptor 在序列化时无从下手,无法正确地排除或者包含属性。

如何解决?

我们可以通过手动将文档对象转化为普通的 JavaScript 对象来解决这个问题。这可以通过 Mongoose 提供的 toJSON() 方法来完成。

@Get()
async findAll(): Promise<Cat[]> {
  const cats = await this.catsService.findAll();

  return cats.map((cat) => cat.toJSON());
}

在这里,我们将从数据库中查询得到的文档对象,手动转化为普通的 JavaScript 对象。这样,在序列化时,ClassSerializerInterceptor 就能够正确地排除或者包含属性了。

总结

ClassSerializerInterceptor 在 Mongoose 中不起作用是因为 Mongoose 的文档对象是以方法的形式封装的,而不是简单的 JavaScript 对象。解决方法是手动将文档对象转化为普通的 JavaScript 对象,然后再进行序列化。