如何在NestJS中验证路径参数id为正数且不使用类包裹?
在NestJS中验证路径参数(无需类包裹)
要验证路径参数id为大于0的正整数,且不用类包裹的话,这里提供几种实用方案:
方案一:自定义可复用验证管道
创建一个专门校验正整数的管道,适合多处复用的场景:
- 新建
positive-int.pipe.ts文件:
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common'; @Injectable() export class PositiveIntPipe implements PipeTransform { transform(value: any) { const num = parseInt(value, 10); if (isNaN(num) || num <= 0) { throw new BadRequestException('id必须是大于0的正整数'); } return num; } }
- 在控制器方法中直接使用:
update(@Param('id', PositiveIntPipe) id: number, @Body() updateSite: UpdateSiteDto) { // 此时id已经是经过校验的正整数,可直接使用 }
方案二:结合ParseIntPipe做临时校验
如果只是单个地方使用,不想单独建管道,可以先通过ParseIntPipe把参数转成数字,再手动校验:
import { ParseIntPipe, BadRequestException } from '@nestjs/common'; update( @Param('id', ParseIntPipe) id: number, @Body() updateSite: UpdateSiteDto ) { if (id <= 0) { throw new BadRequestException('id必须是大于0的正整数'); } // 后续业务逻辑 }
方案三:用class-validator的@Validate装饰器
借助class-validator的自定义验证器,直接在参数上标记校验规则:
- 新建
is-positive.validator.ts验证器文件:
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator'; @ValidatorConstraint({ name: 'isPositive', async: false }) export class IsPositiveConstraint implements ValidatorConstraintInterface { validate(value: any, args: ValidationArguments) { return typeof value === 'number' && value > 0; } defaultMessage(args: ValidationArguments) { return 'id必须是大于0的正整数'; } }
- 在控制器中引入并使用,注意要确保项目全局配置了
ValidationPipe:
import { Validate } from 'class-validator'; import { IsPositiveConstraint } from './is-positive.validator'; import { ParseIntPipe } from '@nestjs/common'; update( @Param('id', ParseIntPipe) @Validate(IsPositiveConstraint) id: number, @Body() updateSite: UpdateSiteDto ) { // 校验通过后执行逻辑 }
全局配置ValidationPipe的方式(在main.ts中):
import { ValidationPipe } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); await app.listen(3000); } bootstrap();
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

