使用Prisma时如何用DTO验证NestJS请求体并禁止更新ID
解决NestJS中阻止客户端传入DTO未定义字段的问题
要彻底阻止客户端传入id这类无需更新的字段,无需给每个字段添加@IsEmpty(),只需调整ValidationPipe的配置即可,这是最简洁高效的方案:
核心解决方案:配置ValidationPipe过滤非法字段
默认情况下,NestJS的ValidationPipe只会验证DTO中定义的字段,但不会移除请求体里的其他字段——这就是客户端传id能被Prisma接收并更新的原因。只需开启两个关键配置:
whitelist: true:自动移除请求体中未在DTO里定义的属性forbidNonWhitelisted: true:若客户端传入未定义属性,直接抛出400错误(可根据业务需求选择是否开启)
修改启动代码:
async function bootstrap() { const app = await NestFactory.create<NestFastifyApplication>( AppModule, new FastifyAdapter({ logger: true }), ); app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, // 可选:将请求体转换为DTO类实例,增强类型安全性 })); await app.listen(3000); } bootstrap();
局部配置(可选)
如果不想全局生效,也可以在控制器的@Body()装饰器中单独配置:
@Patch('/:id') async updateOne( @Param('id') id: User['id'], @Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true })) data: UserUpdateDto, ): Promise<boolean> { await this.userService.updateOne({ where: { id }, data }); return true; }
补充说明
- DTO中的
implements Pick<Prisma.UserUpdateInput, 'email' | 'name'>可以保留,它仅做类型层面的约束,确保DTO与Prisma模型的可更新字段同步,不影响运行时的字段过滤。 - 开启
transform: true后,请求体将被转换成UserUpdateDto实例,能进一步避免类型不一致问题。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

