如何在Nest.js中通过@Query装饰器获取嵌套结构的URL查询参数
NestJS 嵌套查询参数解析解决方案
根因说明
NestJS 底层默认的 Express 适配器默认使用的查询参数解析规则不会自动解析方括号格式的嵌套参数,会直接将createdAt[lte]这类参数名作为字符串键存入query对象,不会生成嵌套结构。
解决方案
方案1:全局开启嵌套解析(推荐)
直接在应用启动配置中修改 Express 的查询解析器配置,全局所有接口都会自动支持嵌套查询参数解析:
- 修改
main.ts启动代码:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule, { queryParser: { extended: true, depth: 10, // 可根据业务需要调整允许的最大嵌套层级 } }); // 若需要自动转换参数类型(比如limit从字符串转数字),加全局校验管道 app.useGlobalPipes(new ValidationPipe({ transform: true, })); await app.listen(3000); } bootstrap();
配置完成后直接用你原本的代码就能拿到预期的嵌套createdAt结构,limit也会自动转为数字类型。
方案2:单接口手动转换(无需修改全局配置)
如果仅需要个别接口支持嵌套解析,可配合class-transformer定义DTO做手动转换:
- 安装依赖
npm install class-transformer class-validator
- 定义DTO类(不能用interface,运行时会丢失元数据)
import { Transform, Type } from 'class-transformer'; import { IsIn, IsNumber, IsString, IsOptional } from 'class-validator'; export class QueryDto { @IsString() key1: string; @IsString() key2: string; @IsString() key3: string; @IsOptional() @IsString() key4?: string; @Transform(({ obj }) => ({ lte: obj['createdAt[lte]'], gte: obj['createdAt[gte]'] })) createdAt: { lte: string; gte: string; }; @IsIn(['desc', 'asc']) orderBy: 'desc' | 'asc'; @Type(() => Number) @IsNumber() limit: number; }
- 控制器中使用DTO
@Get('route') getAll(@Query() query: QueryDto): Promise<void> { return this.myService.findAll(query); }
注意事项
- 如果使用Fastify作为底层适配器,需要安装
@fastify/qs插件开启嵌套解析,配置方式类似。 - 两种方案都能同时解决limit参数为字符串的问题,无需额外手动转换。
内容的提问来源于stack exchange,提问作者LaCodeM
相关产品推荐
相关产品推荐

