简体   繁体   English

NestJS:如何使用自定义装饰器访问控制器功能响应?

[英]NestJS: How can I access controller function response using a custom decorator?

This is my decorator这是我的装饰器

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

export const CacheData = createParamDecorator(
    (data: any, ctx: ExecutionContext) => {
        const request = ctx.switchToHttp().getRequest();
        console.log(request.url, request.method, 'request');
        const response = ctx.switchToHttp().getResponse();
        const reqBody = request.body;
        console.log(reqBody, 'reqBody');
        console.log(response.raw.req.data, 'response');
        console.log(response.raw.req.body, 'response');
        console.log(response.raw.data, 'response');
        console.log(response.cacheData, 'response');
    }
);

in my controller function I'm using the decorator as follows:在我的控制器函数中,我使用装饰器如下:

getStringsArr(
    @Headers('Authorization') auth: string,
    @Headers('Country') country = 'DK',
    @CacheData() cacheData,
  ): Array<string> {
return ['Hello', 'World', '!'];
}

so how can I access response data in my CacheData decorator?那么如何在我的 CacheData 装饰器中访问响应数据呢?

Your CacheData decorator is a param decorator, which means, as far as I know, that it will be executed only when the method handler is called.您的CacheData装饰器是一个 param 装饰器,这意味着,据我所知,它只会在调用方法处理程序时执行。 You have a few options.你有几个选择。 Here are two.这是两个。

Option A - Method decorator选项 A - 方法装饰器

A method decorator would give you access to the returned data from your function but comes with drawbacks: you don't have access to the execution context, unlike the param decorator and injecting customer services is less elegant.方法装饰器可以让您访问函数返回的数据,但也有缺点:您无权访问执行上下文,这与参数装饰器不同,并且注入客户服务不太优雅。 I like this option because it is easy to supply parameters to the decorator.我喜欢这个选项,因为它很容易为装饰器提供参数。

Since your example is around caching, I suspect you'll want to inject your service there, so option B is probably more fitted to your requirements, but here's an implementation with a method decorator:因为你的例子是关于缓存的,我怀疑你会想在那里注入你的服务,所以选项 B 可能更适合你的要求,但这里有一个带有方法装饰器的实现:

const MyMethodDecorator = (params) => {
  return (
    target: Record<string, unknown>,
    _propertyKey: string,
    descriptor: PropertyDescriptor,
  ) => {
    const originalMethod = descriptor.value;
    descriptor.value = async function (...args) {
      const data = await originalMethod.apply(this, args);
      // data = ['Hello', 'World', '!'] 
    };

    return descriptor;
  };
};

@MyMethodDecorator({ ttl: 120, cacheKey: 'stringsArr' })
getStringsArr(
  @Headers('Authorization') auth: string,
  @Headers('Country') country = 'DK'
): Array<string> {
  return ['Hello', 'World', '!'];
}

Option B - Route Interceptor选项 B - 路由拦截器

Interceptors make dependency injection easy since it's like any other NestJS service.拦截器使依赖注入变得容易,因为它就像任何其他 NestJS 服务一样。 I recommend reading and understanding the request lifecycle is you choose this option.如果您选择此选项,我建议您阅读并理解请求生命周期

One drawback vs a decorator is that supplying parameters is less elegant but is doable using reflection and a method decorator:与装饰器相比,一个缺点是提供参数不太优雅,但可以使用反射和方法装饰器来实现:

import { applyDecorators, SetMetadata, UseInterceptors } from '@nestjs/common';

@Injectable()
export class MyInterceptor implements NestInterceptor {

  constructor(private readonly reflector: Reflector) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const params = this.reflector.get('MyInterceptorMetadataKey', context.getHandler());
    // params = { ttl: 120, cacheKey: 'stringsArr' }

    return next.handle().pipe(
      tap((response) => {
        // data = ['Hello', 'World', '!'] 
      }),
    );
  }
}

const MyMethodDecorator = (params) => 
    applyDecorators(SetMetadata('MyInterceptorMetadataKey', params));

@UseInterceptors(MyInterceptor)
@MyMethodDecorator({ ttl: 120, cacheKey: 'stringsArr' })
getStringsArr(
  @Headers('Authorization') auth: string,
  @Headers('Country') country = 'DK'
): Array<string> {
  return ['Hello', 'World', '!'];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能在构造函数中使用我的 nestjs 自定义装饰器? - Why can't I use my nestjs custom decorator in a constructor? nestjs 无法在自定义装饰器中注入依赖项 - nestjs can't inject dependency in custom decorator 如何在 Nestjs 中使用 globalPipse 进行自定义响应 - How to make custom response using globalPipse in nestjs 如何在自定义装饰器中使用 NestJS 反射器? - How to use NestJS Reflector inside a Custom Decorator? 我如何对 NestJS 中的 controller 应用防护装置进行单元测试? - How can I unit test that a guard is applied on a controller in NestJS? 我在我的 nestJS 应用程序(使用 authGuard)中使用了passport-jwt auth 策略,如何访问我的控制器中的令牌有效负载? - I'm using a passport-jwt auth strategy in my nestJS app (with authGuard), how to get access to the token payload in my controller? 如何在 NestJS GraphQL 解析器中访问响应 object - How to access Response object in NestJS GraphQL resolver 如何在 Nestjs 的 pipe 中进行自定义响应 - How to make custom response in pipe of nestjs NestJs 在 @Cron 装饰器上使用环境配置 - NestJs Using Environment Configuration on @Cron decorator @nestjs/typeorm 如何在自定义装饰器中获取与 v0.3.0 的 typeorm 的当前连接? - @nestjs/typeorm How to get current connection with v0.3.0 of typeorm in a custom decorator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM