You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中如何通过单注解DTO验证后移除属性并转换请求Payload

在NestJS中通过单个DTO实现请求Payload的验证、转换与属性移除

实现思路

借助NestJS默认集成的class-validator做属性校验,class-transformer完成字段映射与属性清理,通过单个DTO类整合所有逻辑:

  1. 接收并校验reqType必须等于"foo"
  2. 将请求里的source映射为业务对象的from,target映射为to
  3. 校验通过后自动移除reqType字段

步骤1:安装依赖

确保项目已安装所需工具库:

npm install class-validator class-transformer

步骤2:定义DTO类

创建BusinessRequestDto,结合校验与转换装饰器实现需求:

import { IsString, IsEqual } from 'class-validator';
import { Exclude, Expose } from 'class-transformer';

// 默认排除所有未标记@Expose的属性
@Exclude()
export class BusinessRequestDto {
  // 接收reqType并校验其值必须为"foo"
  @Expose()
  @IsString()
  @IsEqual('foo', { message: 'reqType必须为"foo"' })
  reqType: string;

  // 将请求中的source字段映射为业务字段from
  @Expose({ name: 'source' })
  @IsString()
  from: string;

  // 将请求中的target字段映射为业务字段to
  @Expose({ name: 'target' })
  @IsString()
  to: string;
}

步骤3:在控制器中配置ValidationPipe

通过ValidationPipe的配置,实现自动转换、校验,并移除reqType:

import { Controller, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
import { BusinessRequestDto } from './dto/business-request.dto';

@Controller('business')
export class BusinessController {
  @Post('process')
  @UsePipes(new ValidationPipe({
    transform: true, // 自动将请求Payload转换为DTO实例
    transformOptions: {
      excludeExtraneousValues: true, // 只保留@Expose标记的字段
      afterTransform: (instance: BusinessRequestDto) => {
        // 校验通过后移除reqType字段
        delete instance.reqType;
        return instance;
      },
    },
    whitelist: true, // 自动清理DTO中未定义的额外属性
  }))
  async handleRequest(@Body() dto: BusinessRequestDto) {
    // 此处dto已完成转换与校验,结构为{ from: "001", to: "xyz" }
    return dto;
  }
}

效果验证

当请求Payload为:

{"reqType": "foo", "source": "001", "target": "xyz"}

经过DTO处理后,得到的业务对象为:

{"from": "001", "to": "xyz"}

若reqType不为"foo",则会直接抛出校验错误。

内容的提问来源于stack exchange,提问作者pointyhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:13:12