You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS如何向CacheKey装饰器传递动态请求参数?

动态生成NestJS缓存键的实现方案

默认的@CacheKey装饰器无法直接传入运行时的请求参数——因为装饰器是在类初始化阶段执行的,拿不到请求上下文。不过有两种可靠的方式实现你要的动态缓存键逻辑:

方案一:自定义CacheInterceptor(兼容所有NestJS版本)

继承默认的CacheInterceptor,重写trackBy方法来生成符合要求的缓存键:

// custom-cache.interceptor.ts
import { CacheInterceptor, ExecutionContext } from '@nestjs/common';

export class CustomCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    const request = context.switchToHttp().getRequest();
    // 根据实际需求获取请求参数,比如URL参数、Query、Body等
    const userId = request.query.userId; 
    // 拼接成「模块名-方法名-请求参数」格式的缓存键
    return `userModule_getUserById_${userId}`;
  }
}

然后在控制器中替换默认拦截器:

import {
  CacheTTL,
  Controller,
  Get,
  Req,
  UseInterceptors,
} from '@nestjs/common';
import { AppService } from './app.service';
import { CustomCacheInterceptor } from './custom-cache.interceptor';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @UseInterceptors(CustomCacheInterceptor)
  @CacheTTL(3600)
  @Get()
  async getHello(@Req() req: Request): Promise<string> {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('Hello World!');
      }, 3000);
    });
  }
}

方案二:使用CacheKey工厂函数(NestJS 9+支持)

如果你的NestJS版本在9及以上,@CacheKey支持传入工厂函数,直接通过上下文获取请求参数:

import {
  CacheInterceptor,
  CacheKey,
  CacheTTL,
  Controller,
  Get,
  Req,
  UseInterceptors,
  ExecutionContext,
} from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @UseInterceptors(CacheInterceptor)
  @CacheTTL(3600)
  @CacheKey((context: ExecutionContext) => {
    const request = context.switchToHttp().getRequest();
    const userId = request.query.userId;
    return `userModule_getUserById_${userId}`;
  })
  @Get()
  async getHello(@Req() req: Request): Promise<string> {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('Hello World!');
      }, 3000);
    });
  }
}

缓存清理实现

后续要按模块名、方法名或用户ID清理缓存,可通过CacheManager操作:

import { Inject, CACHE_MANAGER } from '@nestjs/common';
import { Cache } from 'cache-manager';

// 在服务/控制器中注入缓存管理器
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

// 清理指定用户的缓存
async clearUserCache(userId: string) {
  const targetKey = `userModule_getUserById_${userId}`;
  await this.cacheManager.del(targetKey);
}

// 批量清理整个userModule的缓存(需缓存存储支持keys查询,如Redis)
async clearUserModuleCache() {
  const moduleKeys = await this.cacheManager.store.keys('userModule_*');
  await Promise.all(moduleKeys.map(key => this.cacheManager.del(key)));
}

内容的提问来源于stack exchange,提问作者Yasin Bikmazer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:50:33