首页 > 解决方案 > 如何使用注释将值添加到 nestjs 执行上下文

问题描述

假设我有一个带有几个方法的控制器类,并且我想注释一个方法以便它在我的执行上下文中创建一个值,是否可以这样做?


@Controller('docs')
export class MyController {
  constructor(private readonly service: SubjectsService) {}
   
  ...
  
  @Get('/:Id')
  @MyAnnotation('addThisStringToContext')    <--- something like this?
  async find(@Param() id: string) {
    return await this.service.find(id);
  }
  
  ...

}

我尝试使用装饰器,但找不到在其中获取执行上下文的方法。

我也尝试过使用拦截器,但我不知道如何将值传递给它。

标签: typescriptnestjs

解决方案


装饰器不能将数据添加到外部对象(如 ExecutionContext),因为它们不作用于该对象,而是作用于类、类方法、类属性或类方法参数。但是,您可以做的是反映该值(Reflect直接使用或使用 Nest 的@SetMetadata()装饰器),然后Reflector稍后使用该类(在警卫、拦截器或过滤器中)并使用this.reflector.get('MetadataKey', context.getHandler()/context.getClass())(类或处理程序,具体取决于位置元数据已设置)。一个例子可能看起来像

// app.controller.ts
@Controller('app')
export class AppController {

  @Get()
  @UseInterceptor(AppInterceptor)
  @SetMetadata('SomeAnnotatedDecorator', 'this is the value')
  doSomethingForApp(@Req() req) {
    return req.metadataValue;
  }
}

// app.interceptor.ts

@Injectable()
export class AppInterceptor {
  constructor(private readonly reflector: Reflector) {}

  intercept(context: ExecutionContext, next: CallHandler) {
    const req = context.switchToHttp().getRequest();
    const metaValue = this.reflector.get('SomeAnnotedDecorator', context.getHandler());
    req.metadataValue = metaValue;
    return next.handle();
  }
}

现在,如果您提出类似的请求

curl http://localhost:3000/app

你应该得到回复

this is the value

推荐阅读