NestJS如何合并多个参数装饰器并获取所有对应取值
合并多个NestJS参数装饰器的实现方案
问题原因
你之前使用applyDecorators实现无法满足需求的核心原因是:applyDecorators仅会按顺序执行传入的装饰器,每个装饰器的返回值会直接作为参数的取值,后执行的装饰器返回值会覆盖之前的结果,因此只能拿到最后一个装饰器的返回值,无法实现聚合多个装饰器取值的需求。
实现方案
使用NestJS内置的createParamDecorator自定义参数装饰器,在装饰器工厂函数内通过ExecutionContext取出所有需要的字段,聚合为一个对象返回即可。示例实现如下:
1. 定义组合装饰器
import { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { getQuery, getHeaders, getCookies } from '@nestjs/platform-express'; // 导入自定义装饰器的取值逻辑,建议提前将自定义装饰器的核心逻辑抽为可复用函数 // 示例:抽出自定义装饰器的取值逻辑(方便复用) const getFirstDecoratorValue = (ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); // 此处替换为你原来@MyFirstDocrator()的取值逻辑 return request.customFirstValue; }; const getSecondDecoratorValue = (ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); // 此处替换为你原来@MySecondDocrator()的取值逻辑 return request.customSecondValue; }; // 定义组合装饰器 export const MyCombinedDecorator = createParamDecorator( (_, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return { query: getQuery(request), // 等价于原@Query()的返回值 userAgent: getHeaders(request)['user-agent'], // 等价于原@Headers('user-agent')的返回值 firstDecorator: getFirstDecoratorValue(ctx), // 等价于原@MyFirstDocrator()的返回值 secondDecorator: getSecondDecoratorValue(ctx), // 等价于原@MySecondDocrator()的返回值 referer: getHeaders(request)['referer'], // 等价于原@Headers('Referer')的返回值 sessionId: getCookies(request)['session'], // 等价于原@Cookies('session')的返回值 }; }, );
2. 使用组合装饰器
@Controller('api') export class MyController { @Get('mainresponse') public getResponse( // 可根据需要定义更严格的类型替代any @MyCombinedDecorator() decorator: { query: Partial<IBean>, userAgent: string, firstDecorator: string, secondDecorator: string, referer: string, sessionId?: string } ): Observable<IResponse> { // 直接通过属性访问对应值即可 console.log(decorator.userAgent, decorator.query); // 原有业务逻辑 ...... } }
注意事项
- 如果你使用Fastify作为HTTP底层框架,只需将导入的
getQuery/getHeaders等工具替换为@nestjs/platform-fastify对应的导出即可,也可以直接从request实例上直接读取对应属性。 - 提前抽离自定义装饰器的取值逻辑,可以避免逻辑重复编写,后续修改也只需调整一处即可。
内容的提问来源于stack exchange,提问作者Rikhil Arora
相关产品推荐
相关产品推荐

