app.useGlobalPipes(new ValidationPipe({ whitelist: true }))
是 NestJS 中用于 全局启用数据验证和过滤 的配置。以下是其核心作用和关键细节:
核心作用
数据验证:
- 使用
class-validator
库对传入的请求体(如@Body()
、@Query()
)进行验证,确保数据符合 DTO(数据传输对象)定义的规则(如类型、必填性等)。 - 例如:
@IsEmail()
、@MinLength(6)
等装饰器会触发对应验证。
- 使用
数据转换:
- 使用
class-transformer
库将原始请求数据转换为 DTO 类的实例,确保类型匹配(如将字符串转换为数字)。
- 使用
字段过滤(白名单机制):
whitelist: true
表示启用白名单模式,仅保留 DTO 类中显式声明的字段,过滤掉请求中未在 DTO 中定义的字段。
#### . class-validator
装饰器的作用
字段的存在性检测:
- 如果字段未添加任何
class-validator
装饰器(如@IsString()
、@IsOptional()
),class-transformer
可能无法识别该字段,导致其被whitelist
过滤。
- 如果字段未添加任何
- 解决方案:即使字段不需要验证,也需添加
@IsOptional()
等装饰器。
非安全性要求高,不建议开启{ whitelist: true },会过滤未显性声明的字段,例如下面DTO遇到的坑
// create-menu.dto.ts import { ApiProperty } from "@nestjs/swagger"; import { IsNotEmpty, IsOptional } from "class-validator"; export class CreateMenuDto { @IsNotEmpty({ message: '菜单标题不能为空' }) @ApiProperty({ example: '菜单标题', description: '菜单标题' }) title: string; @ApiProperty({ example: 1, description: '菜单排序' }) order: number; @IsOptional() @ApiProperty({ example: 1, required: false, description: '父级菜单id' }) parentId?: number; @ApiProperty({ example: 1, description: '菜单类型1:目录 2:菜单 3:按钮' }) type: number; @ApiProperty({ example: 'icon', description: '菜单图标' }) icon: string; @IsOptional() @ApiProperty({ example: 'AA/BB', required: false, description: '组件路径' }) component?: string; @IsNotEmpty({ message: '路由不能为空' }) @ApiProperty({ example: 'aa', description: '路由' }) path: string; @ApiProperty({ example: 1, description: '创建者ID' }) createBy: number; @IsOptional() @ApiProperty({ example: 'sys:post:list', required: false, description: '权限标识' }) permission?: string; } 5. ```
发送数据
{
"title": "菜单标题",
"order":"1",
"parentId": 1,
"type": 1,
"icon": "icon",
"component": "AA/BB",
"path": "aa",
"createBy": 1,
"permission": "sys:post:list"
}
会返回
{
"title": "菜单标题",
"parentId": 1,
"component": "AA/BB",
"path": "aa",
"permission": "sys:post:list"
}
DTO中未使用class-validator
声明的字段都会被过滤