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

NestJs中请求URL缺失Path Param时的自定义处理方案咨询

解决NestJS中DELETE路由无参数时返回404而非校验错误的问题

问题原因

你给同一个方法添加了@Delete('/remove')和@Delete('/remove/:id')两个路由装饰器,Nest的路由匹配机制会优先匹配不带参数的路由,导致所有指向/remove/:id的请求也被前者拦截,无法正确获取id参数,进而导致原路由失效。

解决方案

方案一:使用可选路由参数

将路由改为可选参数形式,让同一个方法同时处理带id和不带id的请求,利用DTO校验拦截空id的情况:

@Delete('remove/:id?')
removePartner(@Param() param: ParamDto) {
  return this.service.delete(param.id);
}

此时:

  • 请求/remove时,param.id为undefined,会触发ParamDto中的@IsNotEmpty()校验
  • 请求/remove/:id时,正常校验id是否为合法MongoId并执行删除逻辑

需要确保全局启用ValidationPipe并配置自定义错误格式(在main.ts中):

import { ValidationPipe, BadRequestException } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe({
    transform: true,
    whitelist: true,
    forbidNonWhitelisted: true,
    // 自定义校验错误返回格式
    exceptionFactory: (errors) => {
      const formattedErrors = errors.map(err => ({
        field: err.property,
        message: Object.values(err.constraints).join(', ')
      }));
      return new BadRequestException({
        message: '参数校验失败',
        errors: formattedErrors
      });
    }
  }));
  await app.listen(3000);
}
bootstrap();

方案二:拆分两个独立路由方法

如果不想使用可选参数,可以创建两个方法分别处理两种请求:

// 处理无id的DELETE请求,触发校验
@Delete('remove')
removePartnerWithoutId(@Param() param: ParamDto) {
  // 无需额外逻辑,DTO校验会自动拦截空id的情况
}

// 处理带id的DELETE请求
@Delete('remove/:id')
removePartner(@Param() param: ParamDto) {
  return this.service.delete(param.id);
}

这种方式下两个路由互不干扰,无id请求会进入第一个方法触发校验,带id请求正常执行删除逻辑。

关键注意事项

  • 必须全局启用ValidationPipe,否则DTO的校验注解不会生效
  • 通过exceptionFactory自定义错误格式,确保返回符合需求的自定义错误,而非Nest默认格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:15:01