Appearance
响应
序列化类(序列化)用于对返回给客户端的数据进行转换处理,比如控制用户密码字段不返回。序列化使用 class-transformer 扩展包完成,你也可以参考 nest官方文档的 序列化 章节。
声明定义
序列化使用拦截器进行处理,我们可以在全局,控制器,方法等处进行定义。
全局定义
修改 main.ts 主文件
import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'
import { NestFactory, Reflector } from '@nestjs/core'
import { AppModule } from './app.module'
async function bootstrap() {
const app = await NestFactory.create(AppModule)
...
//全局定义序列化拦截器
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)))
await app.listen(3000)
}
bootstrap()
控制器
也可以在控制器中声明序列化
import { Body, ClassSerializerInterceptor, Controller, SerializeOptions, UseInterceptors } from '@nestjs/common'
...
@Controller('article')
@UseInterceptors(ClassSerializerInterceptor)
export class ArticleController {
constructor(private readonly articleService: ArticleService) {}
...
}
方法
也支持在方法中定义序列化
import { Body, ClassSerializerInterceptor, Controller, SerializeOptions, UseInterceptors } from '@nestjs/common'
...
@UseInterceptors(ClassSerializerInterceptor)
@Get(':id')
async findOne(@Param('id') id: string) {
...
}
过滤选项
我们使用 @SerializeOptions() 对响进行配置,然后在响应类中对属性进行细节定义。
选项 | 说明 | 示例 |
---|---|---|
strategy | exposeAll:包含所有属性 excludeAll:排除所有属性 | @SerializeOptions({ strategy: 'exposeAll' }) |
excludePrefixes | 排除某个前缀的属性 | @SerializeOptions({ strategy: 'exposeAll',excludePrefixes: ['_'] }) |
下面是在控制器中对过滤选项的定义
import { Body, ClassSerializerInterceptor, Controller, SerializeOptions, UseInterceptors } from '@nestjs/common'
...
@Controller('article')
@UseInterceptors(ClassSerializerInterceptor)
//定义序列化选项
@SerializeOptions({ strategy: 'exposeAll' })
export class ArticleController {
constructor(private readonly articleService: ArticleService) {}
...
}
响应类
下面定义 entitys/article.entitys.ts 类,来对响应结果进行处理
import { category, user } from '@prisma/client'
import { Exclude, Expose, Transform } from 'class-transformer'
import dayjs from 'dayjs'
export default class Article {
//包含属性
@Expose()
title: string
//排除属性
@Exclude()
content: string
//序列化类的category栏目模型只包含标题
@Transform(({ value, key, obj, type }) => {
return obj[key].title
})
category: category
//序列化类的日期使用dayjs进行格式化
@Transform(({ value }) => dayjs(value).format('YYYY-MM-DD'))
createdAt: Date
//构造函数用于传递序列化类数据
constructor(options: Partial<Article>={}) {
Object.assign(this, options)
}
}
使用方法
经过上面的学习,我们已经对nest.js 的响应掌握了,下面通过例子把这个过程走一遍。
响应类
下面通过文件 entitys/article.entity.ts 对响应结果进行定义
import { category } from '@prisma/client'
import { Exclude, Expose, Transform } from 'class-transformer'
export default class Article {
@Expose()
id: number
@Exclude()
content: string
@Transform((value) => 'eee')
title: string
@Expose()
category: category
constructor(partial: Partial<Article> = {}) {
Object.assign(this, partial)
}
}
控制器
下面在控制器方法中使用响应类对返回客户端的结果进行处理,我们有多种方式可以操作。
import Article from './entitys/article.entity'
...
@Controller('article')
@UseInterceptors(ClassSerializerInterceptor)
@SerializeOptions({ strategy: 'excludeAll'})
export class ArticleController {
constructor(private readonly articleService: ArticleService) {}
@Get(':id')
async findOne(@Param('id') id: string) {
const article = await this.articleService.findOne(+id)
return new Article(article)
}
}
也可以使用 plainToClass 方法进行序列化,这时可以不用定义 UseInterceptors 与 SerializeOptions
@Controller()
export class AppController {
@Get()
getHello(@User() user: UserDto) {
const users = new PrismaClient().user.findMany()
return plainToClass(UserDto, users)
}
}