文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Nest.js参数校验和自定义返回数据格式的示例分析

2023-06-14 08:37

关注

这篇文章主要介绍Nest.js参数校验和自定义返回数据格式的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

0x0 参数校验

参数校验大部分业务是使用 Nest.js 中的管道 方法实现,具体可以查阅文档 。不过编写过程中遇到一些问题,虽然文档讲得比较晦涩。

在做个查询接口,里面包含一些参数,做成 dto 结构数据:

import { ApiProperty } from '@nestjs/swagger'export class QueryUserDto { @ApiProperty({ required: false, description: '页码' }) readonly currentPage: number @ApiProperty({ required: false, description: '条数' }) readonly pageSize: number @ApiProperty({ required: false, description: '用户账号' }) readonly username?: string @ApiProperty({ required: false, description: '用户状态' }) readonly activeStatus: number @ApiProperty({ required: false, description: '排序的方式: ASC, DESC' }) readonly order: 'DESC' | 'ASC'} TYPESCRIPT

在 @Query 请求传入对应的参数,发现得到的数据类型都是 String ,然后查阅相关文档才明白还需要 class-transformer 的 Type 进行转换:

import { ApiProperty } from '@nestjs/swagger'import { Type } from 'class-transformer'export class QueryUserDto { @ApiProperty({ required: false, description: '页码' }) @Type(() => Number) readonly currentPage: number = 1 @ApiProperty({ required: false, description: '条数' }) @Type(() => Number) readonly pageSize: number = 10 @ApiProperty({ required: false, description: '用户账号' }) readonly username?: string @ApiProperty({ required: false, description: '用户状态' }) @Type(() => Number) readonly activeStatus: number = 3 @ApiProperty({ required: false, description: '排序的方式: ASC, DESC' }) readonly order: 'DESC' | 'ASC' = 'DESC'}

然后在 ValidationPipe 管道方法里开启 transform 选项:

app.useGlobalPipes( new ValidationPipe({ transform: true }))

或者在 app.modules.ts 注入:

import { ValidationPipe } from '@nestjs/common'import { APP_PIPE } from '@nestjs/core'@Module({ imports: [ // ... ], controllers: [AppController], providers: [ {  provide: APP_PIPE,  useValue: new ValidationPipe({  transform: true  }) } ]})

俩者使用方法区别于程序的是否混合应用类型。

我这边为了省事直接写在全局方法里,最终到 service 拿到的数据就是经过管道业务处理过的数据,不需要在 service 层进行大量的数据类型判断。

0x1 自定义返回数据格式

在 controller 返回的数据都是从数据库表结构而来:

{ "id": "d8d5a56c-ee9f-4e41-be48-5414a7a5712c", "username": "Akeem.Cremin", "password": "$2b$10$kRcsmN6ewFC2GOs0TEg6TuvDbNzf1VGCbQf2fI1UeyPAiZCq9rMKm", "email": "Garrett87@hotmail.com", "nickname": "Wallace Nicolas", "role": "user", "isActive": true, "createdTime": "2021-03-24T15:24:26.806Z", "updatedTime": "2021-03-24T15:24:26.806Z"}

如果需要定义最终返回接口的数据格式例如:

{ "statusCode": 200, "message": "获取成功", "data": {  "id": "d8d5a56c-ee9f-4e41-be48-5414a7a5712c",  "username": "Akeem.Cremin",  "password": "$2b$10$kRcsmN6ewFC2GOs0TEg6TuvDbNzf1VGCbQf2fI1UeyPAiZCq9rMKm",  "email": "Garrett87@hotmail.com",  "nickname": "Wallace Nicolas",  "role": "user",  "isActive": true,  "createdTime": "2021-03-24T15:24:26.806Z",  "updatedTime": "2021-03-24T15:24:26.806Z" }}

这里就需要做个自定义成功请求拦截器:

nest g in shared/interceptor/transform
import { CallHandler, ExecutionContext, Injectable, Logger, NestInterceptor } from '@nestjs/common'import { Observable } from 'rxjs'import { map } from 'rxjs/operators'import { Request } from 'express'interface Response<T> { data: T}@Injectable()export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> { intercept(context: ExecutionContext, next: CallHandler<T>): Observable<any> { const request = context.switchToHttp().getRequest<Request>() Logger.log(request.url, '正常接口请求') return next.handle().pipe(  map(data => {  return {   data: data,   statusCode: 200,   message: '请求成功'  }  }) ) }}

然后在 app.module.ts 引入即可使用:

import { ValidationPipe } from '@nestjs/common'import { APP_INTERCEPTOR } from '@nestjs/core'import { TransformInterceptor } from '@/shared/interceptor/transform.interceptor'@Module({ imports: [ // ... ], controllers: [AppController], providers: [ {  provide: APP_INTERCEPTOR,  useClass: TransformInterceptor } ]})

不过 APP_INTERCEPTOR 排序要注意,TransformInterceptor 最好放在第一个,否则会失效。

错误过滤器:

nest g f shared/filters/httpException
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, Logger } from '@nestjs/common'import { Response, Request } from 'express'@Catch(HttpException)export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const context = host.switchToHttp() const response = context.getResponse<Response>() const request = context.getRequest<Request>() const status = exception.getStatus() const message = exception.message Logger.log(`${request.url} - ${message}`, '非正常接口请求') response.status(status).json({  statusCode: status,  message: message,  path: request.url,  timestamp: new Date().toISOString() }) }}

然后在 app.module.ts 引入即可使用:

import { ValidationPipe } from '@nestjs/common'import { APP_FILTER } from '@nestjs/core'import { HttpExceptionFilter } from '@/shared/filters/http-exception.filter'@Module({ imports: [ // ... ], controllers: [AppController], providers: [ {  provide: APP_FILTER,  useClass: HttpExceptionFilter } ]})

0x2 隐藏实体类中的某个字段

本来想使用 @Exclude 属性来隐藏数据库中一些敏感的字段,但发现无法满足特殊的需求,如果是返回单条实例可以实现隐藏,但是我有个 findAll 就无法实现了,上面在 Serialization | NestJS - A progressive Node.js framework 文档里说的非常详细,不过这里还有个办法。首先在实力类敏感数据字段上添加属性:

import { BaseEntity, Entity, Column, PrimaryGeneratedColumn } from 'typeorm'@Entity('user')export class UserEntity extends BaseEntity { @PrimaryGeneratedColumn('uuid', {  comment: '用户编号' }) id: string @Column({  type: 'varchar',  length: 50,  unique: true,  comment: '登录用户' }) username: string @Column({  type: 'varchar',  length: 200,  select: false,  comment: '密码' }) password: string

select: false 可以在返回查询结果隐藏这个字段,但所有涉及到这个字段查询必须添加这个字段,比如我在 user.service.ts 登录查询中:

const user = await getRepository(UserEntity)   .createQueryBuilder('user')   .where('user.username = :username', { username })   .addSelect('user.password')   .getOne()

.addSelect('user.password') 添加这个属性查询将会包括 password 这个字段,否则普通查询的方法不会包括这个字段。

以上是“Nest.js参数校验和自定义返回数据格式的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯