访问或将变量传递给Nestjs中的拦截器

发布于 2025-02-13 18:27:13 字数 1634 浏览 1 评论 0原文

我是Nestjs的新手,一直在研究一些解决方案,但没有找到方法。 我的API返回用户列表,如果存在或从DB中读取用户,则可以从缓存中读取用户,并且基于此,我需要设置标题。 我希望拦截器能够处理这一部分。

我的控制器

  @UseInterceptors(CacheOrServiceHeaderInterceptor)
  @Get('users')
  public async users(
      @Query('id') clinicianId: number,
      @Query('name') specialtyName: string,
  ){
    const setFlags: MetaFlags = {setCacheHeader: false, setServiceHeader: false};

    const data = await this.service.getUsers(id, name, setFlags);
    return data;
}

我的服务类

export interface MetaFlags {
  setServiceHeader: boolean
  setCacheHeader?: boolean,
}
:
:
public async getUsers(....){
// code that handles whether cache is used or a service is used to get users
 and based on it, the metaFlags are set. setCacheHeader = true if read from cache or setServiceHeader = true if read from DB.

我的拦截器看起来像是这样的

@Injectable()
export class CacheOrServiceHeaderInterceptor implements NestInterceptor {
  
    public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
       
        return next
            .handle()
            .pipe(
                map((data) => {
                    const req = context.switchToHttp().getRequest();
    // this is static but I want a condition here if 
                    if(MetaFlags.setCacheHeader)
                    // set xyz header
                     else set abc header
                    req.res.set('x-api-key', 'pretty secure');
                    return data;
                }
                 
            )
        );}}

方法可以将这些标志传递给拦截器或使拦截器读取这些标志值?

I am new to NestJS and have been looking at a couple of solutions but haven't found a way.
My API returns list of users, the users are either read from the cache if present or from the DB and based on this I need to set the headers.
I want the interceptor to handle this part.

My Controller

  @UseInterceptors(CacheOrServiceHeaderInterceptor)
  @Get('users')
  public async users(
      @Query('id') clinicianId: number,
      @Query('name') specialtyName: string,
  ){
    const setFlags: MetaFlags = {setCacheHeader: false, setServiceHeader: false};

    const data = await this.service.getUsers(id, name, setFlags);
    return data;
}

My service class

export interface MetaFlags {
  setServiceHeader: boolean
  setCacheHeader?: boolean,
}
:
:
public async getUsers(....){
// code that handles whether cache is used or a service is used to get users
 and based on it, the metaFlags are set. setCacheHeader = true if read from cache or setServiceHeader = true if read from DB.

My interceptor looks like this

@Injectable()
export class CacheOrServiceHeaderInterceptor implements NestInterceptor {
  
    public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
       
        return next
            .handle()
            .pipe(
                map((data) => {
                    const req = context.switchToHttp().getRequest();
    // this is static but I want a condition here if 
                    if(MetaFlags.setCacheHeader)
                    // set xyz header
                     else set abc header
                    req.res.set('x-api-key', 'pretty secure');
                    return data;
                }
                 
            )
        );}}

Is there a way to pass these flags to the interceptor or make the interceptor read these flag values ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

标点 2025-02-20 18:27:13

我建议返回应将哪些标题设置为控制器返回服务的一部分。如果您最终使用全球状态,则可以在阅读拦截器并将错误的标头读回端点之前获得多个端点覆盖全局状态的请求。类似于

{
  data: regularDataHere,
  header: 'cache' || 'database'
}

拦截器的MAP,您可以读取data对象,然后删除data属性属性,而不是返回它此标题字段到客户端,读取标题字段,以便您知道要在响应上设置哪个标头。这样的事情:

@Injectable()
export class CacheOrServiceHeaderInterceptor implements NestInterceptor {
  
    public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handler().pipe(
      map((data: { data: DataType, header: 'cache' | 'database' }) => {
        const res = context.switchToHttp().getResponse<ResponseType>();
        if (data.header === 'database') {
          res.setHeader('x-api-key', 'pretty secure');
        } else {
          res.setHeader(xyz, value);
        }
        return data.data;
      })
    );
  }
}

I would suggest returning what header should be set as a part of the service of controller's return. If you end up using a global state, you could get multiple requests to the endpoint overwriting the global state before you read it in the interceptor and send back the wrong header. Something like

{
  data: regularDataHere,
  header: 'cache' || 'database'
}

Now in the map of your interceptor, you can read the data object and pull off the data property to return only it and not expose this header field to the client, and read the header field so you know which header to set on the response. Something like this:

@Injectable()
export class CacheOrServiceHeaderInterceptor implements NestInterceptor {
  
    public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handler().pipe(
      map((data: { data: DataType, header: 'cache' | 'database' }) => {
        const res = context.switchToHttp().getResponse<ResponseType>();
        if (data.header === 'database') {
          res.setHeader('x-api-key', 'pretty secure');
        } else {
          res.setHeader(xyz, value);
        }
        return data.data;
      })
    );
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文