【问题标题】:Nestjs: Retrieve the request / context from a DecoratorNestjs:从装饰器中检索请求/上下文
【发布时间】:2021-10-17 00:48:43
【问题描述】:

我正在开发一个 NestJS 项目, 我正在尝试在记录器中访问 executionContext 以按请求过滤日志。

每个可注射物都有一个记录器实例,我想保持这种行为(因此可注射物的范围是默认值)。

为此,我尝试创建一个装饰器,从请求中获取上下文并将其传递给子服务(如在记录器中),以最终在记录器中获取上下文...

我不确定...现在,这是我的代码:

export const Loggable = () => (constructor: Function) => {
  for (const propertyName of Reflect.ownKeys(constructor.prototype)) {
    let descriptor = Reflect.getOwnPropertyDescriptor(constructor.prototype, propertyName);
    const isMethod = descriptor.value instanceof Function;
    if (!isMethod)
      continue;

    const originalMethod = descriptor.value;
    const routeArgsMetada = Reflect.getMetadata(ROUTE_ARGS_METADATA, constructor, propertyName as string);

    descriptor.value = function (...args: any[]) {
      const result = originalMethod.apply(this, args);
        //TODO : retrieve the request / contextExecution
        //TODO : pass the request / contextExecution to children functions...
      return result;
    };
    Reflect.defineProperty(constructor.prototype, propertyName, descriptor);

    Reflect.defineMetadata(ROUTE_ARGS_METADATA, routeArgsMetada, constructor, propertyName as string);
  }
};

这个@Loggable() 装饰器将附加到所有需要记录或抛出执行上下文的可注入类

这可能吗?如果不是为什么?

PS:我想知道,@Guard 注释如何获取上下文? @Req 注解如何获取请求?

https://github.com/nestjs/nest/tree/master/packages/common/decorators/http

https://github.com/nestjs/nest/blob/master/packages/common/decorators/core/use-guards.decorator.ts

【问题讨论】:

  • 我认为使用您在此处布置的装饰器方法是不可能的。你为什么不为此使用一个自动访问上下文的拦截器?
  • 目标是在记录器服务中获取上下文。如果有可能将它从拦截器扔到服务中,我没有得到解决方案......

标签: node.js typescript express nestjs typescript-decorator


【解决方案1】:

@Req 如何获得请求?

从这里下载 NestJS 的源代码:https://github.com/nestjs/nest

并在 TS 文件中查找“RouteParamtypes.REQUEST”。您可以在这里找到它们:

  • route-params.decorator.ts
  • route-params-factory.ts

正如您所见,装饰器通常不会做太多事情。他们只是将一些元数据添加到类、方法和参数中。其余的都是框架。

这里@Req只在启动时创建一个特殊的参数装饰器,在调用方法之前由RouteParamsFactory处理。

export const Request: () => ParameterDecorator = createRouteParamDecorator(
  RouteParamtypes.REQUEST,
);

所以 @Req 装饰器本身不会检索 Request。它只是要求NestJS框架在调用方法之前用Request的引用填充注解的方法参数。

顺便说一句,我也遇到了和你一样的问题。我也在寻找关于如何从装饰器访问 ExecutionContext 的解决方案。但是装饰器只能访问带注释的目标(类、处理程序、参数...)

我认为 ExecutionContext 只能从以下位置直接访问:

  • 管道
  • 守卫
  • 拦截器

或以这种方式从参数装饰器: https://docs.nestjs.com/custom-decorators#param-decorators

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);

注意:您可以在 create-route-param-metadata.decorator.ts 中找到 createParamDecorator() 的来源。

【讨论】:

    猜你喜欢
    • 2021-09-30
    • 2017-08-05
    • 1970-01-01
    • 2022-01-27
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 2021-08-08
    相关资源
    最近更新 更多