NestJS控制器中如何访问SetMetadata定义的元数据
实现方法
控制器内访问元数据不需要特意获取ExecutionContext实例:
- 守卫、拦截器中使用的ExecutionContext,其
getClass()方法本质是返回当前路由匹配到的控制器类构造函数,getHandler()方法本质是返回匹配到的路由处理方法引用,这两个值在控制器内部可以直接获取,完全不需要依赖ExecutionContext。 - 你仅需要正常注入
Reflector实例,传入对应的类、方法引用即可读取元数据,和守卫中的读取逻辑完全一致。
代码示例
import { Controller, Get, Reflector, SetMetadata } from '@nestjs/common'; import { SOME_METADATA_KEY, EnabledFeatures } from './your-metadata.constants'; // 你通过自定义装饰器/SetMetadata添加的类级元数据 @SetMetadata(SOME_METADATA_KEY, [EnabledFeatures.FeatureA]) @Controller('demo') export class DemoController { constructor(private readonly reflector: Reflector) {} // 可按需添加方法级元数据 @SetMetadata(SOME_METADATA_KEY, [EnabledFeatures.FeatureB]) @Get() getDemoData() { // 读取控制器类级元数据,等价于守卫中context.getClass()的取值 const classLevelMeta = this.reflector.get<EnabledFeatures[]>( SOME_METADATA_KEY, this.constructor ); // 读取当前路由方法级元数据,等价于守卫中context.getHandler()的取值 const methodLevelMeta = this.reflector.get<EnabledFeatures[]>( SOME_METADATA_KEY, this.getDemoData ); // 如需自动合并类和方法级元数据,和守卫中传[context.getClass(), context.getHandler()]效果完全一致 const mergedMeta = this.reflector.get<EnabledFeatures[]>( SOME_METADATA_KEY, [this.constructor, this.getDemoData] ); return { classLevelMeta, methodLevelMeta, mergedMeta } } }
补充说明
如果有特殊场景必须拿到和守卫中完全一致的ExecutionContext实例,NestJS原生支持将其作为请求作用域依赖直接注入,但绝大多数元数据读取场景下,上述写法更简洁,也没有额外的作用域实例化开销,完全满足常规需求。
内容的提问来源于stack exchange,提问作者Ferenc T
相关产品推荐
相关产品推荐

