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

基于现有@nestjs/graphql配置,如何利用Redis缓存Resolver返回的大量数据?

用Redis缓存NestJS GraphQL Resolver的响应结果

我来一步步帮你实现用Redis缓存那个返回大量数据的getRates查询结果,基于你现有的代码和配置:

1. 安装必要依赖

首先得安装NestJS缓存模块和Redis存储适配器:

npm install @nestjs/cache-manager cache-manager cache-manager-redis-store
# 或者用yarn
yarn add @nestjs/cache-manager cache-manager cache-manager-redis-store

2. 配置全局CacheModule(使用Redis作为存储)

在你的AppModule里导入并配置CacheModule,把Redis设置为缓存存储介质,同时设为全局模块方便所有Resolver使用:

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-store';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { graphQLConfig } from './your-graphql-config-path'; // 替换成你的GraphQL配置路径

@Module({
  imports: [
    ConfigModule.forRoot(),
    // 配置Redis缓存模块
    CacheModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        store: await redisStore({
          // 从配置文件读取Redis连接信息,根据你的实际配置调整
          url: configService.get<string>('REDIS_URL'),
          // 如果没有用URL的话,可以单独配置host/port/password:
          // host: configService.get<string>('REDIS_HOST'),
          // port: configService.get<number>('REDIS_PORT'),
          // password: configService.get<string>('REDIS_PASSWORD'),
          ttl: 60, // 默认缓存过期时间(秒),可以根据需求调整
        }),
      }),
      isGlobal: true, // 设为全局模块,避免在每个Resolver模块重复导入
    }),
    // 导入你已有的GraphQL配置
    GraphQLModule.forRootAsync(graphQLConfig),
    // 其他业务模块...
  ],
})
export class AppModule {}

3. 给Resolver方法添加缓存装饰器

在你的getRates查询方法上使用@Cacheable装饰器,指定缓存key的生成规则和过期时间(可选,会覆盖全局TTL):

import { Query, Args, Resolver } from '@nestjs/graphql';
import { Cacheable } from '@nestjs/cache-manager';
import { ConvertRateType } from './your-type-path'; // 替换成你的类型路径
import { GetConvertRatesInput } from './your-input-path'; // 替换成你的输入类型路径
import { RatesService } from './rates.service';

@Resolver()
export class RatesResolver {
  constructor(private readonly _ratesService: RatesService) {}

  @Query(() => [ConvertRateType])
  @Cacheable({
    // 根据请求参数生成唯一缓存key,确保不同输入参数对应不同缓存
    key: (context) => {
      const input = context.args.input;
      // 这里根据你的GetConvertRatesInput结构拼接key,比如包含基础货币、目标货币、日期等
      return `rates:${input.baseCurrency}:${input.targetCurrencies.join(',')}:${input.date}`;
    },
    ttl: 300, // 单独设置这个查询的缓存过期时间(5分钟),可选
  })
  async getRates(
    @Args('input') input: GetConvertRatesInput,
  ): Promise<ConvertRateType[]> {
    const rates = await this._ratesService.getRates(input);
    return rates;
  }
}

4. 可选:手动清除缓存(当数据更新时)

如果你的汇率数据会定期更新,需要清除旧缓存来返回最新数据,可以在RatesService里注入CacheManager来手动删除缓存:

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

@Injectable()
export class RatesService {
  constructor(
    @Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
    // 其他依赖...
  ) {}

  async updateRates() {
    // 执行更新汇率数据的逻辑...
    
    // 清除特定缓存key(根据实际参数生成)
    await this.cacheManager.del('rates:USD:EUR,GBP:2024-05-20');
    
    // 如果需要批量清除所有汇率缓存(生产环境建议用扫描而非keys命令)
    // const keys = await this.cacheManager.store.keys('rates:*');
    // await Promise.all(keys.map(key => this.cacheManager.del(key)));
  }
}

这样配置后,当第一次调用getRates查询时,NestJS会自动把查询结果存入Redis,后续相同参数的查询会直接从Redis返回缓存数据,直到缓存过期或者被手动清除。

内容的提问来源于stack exchange,提问作者Denys Rybkin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 21:47:37