如何在 Nest JS 中创建自定义缓存模块

问题描述 投票:0回答:1

我想问你如何在NestJS中实现自定义CacheModule。现在该指南提供了有关如何将缓存直接连接到 AppModule 应用程序的主模块的信息。但是如果我需要自己定义缓存模块怎么办,如何正确实现呢?

我尝试创建类似的东西,但这不是完全正确的实现,因为例如我想将自定义模块添加为测试模块的依赖项。然后测试不会运行,因为它们根本看不到自定义缓存模块。

自定义.cache.module.ts

@Module({})
export class CustomCacheModule {
  static forRoot(): DynamicModule {
    return {
      imports: [CacheModule.register({ isGlobal: true })],
      module: CustomCacheModule,
      providers: [
        { useClass: CacheService, provide: CACHE_SERVICE },
        { useClass: CalculatorService, provide: CALCULATOR_SERVICE },
        {
          useClass: ExpressionCounterService,
          provide: EXPRESSION_COUNTER_SERVICE,
        },
        {
          useClass: RegExCreatorService,
          provide: REGEXP_CREATOR_SERVICE_INTERFACE,
        },
      ],
      exports: [CustomCacheModule],
    };
  }
}

导入到AppModule看起来像这样,我不喜欢我需要调用forRoot方法,但这是我在这里找到的唯一实现。

app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    CustomCacheModule.forRoot(),
    DBModule,
    HistoryModule,
    CalculatorModule,
  ],
})
export class AppModule {}

为了更好的练习,我将展示我的规范文件。即使我创建了所有依赖项,其中的代码也不起作用。也许你会注意到一个错误。

计算器.控制器.规格.ts

let calculatorController: CalculatorController;
let calculatorService: CalculatorService;

afterAll((done) => {
  mongoose.connection.close();
  done();
});

beforeEach(async () => {
  const moduleRef = await Test.createTestingModule({
    imports: [HistoryModule, CustomCacheModule],
    controllers: [CalculatorController],
    providers: [
      CalculatorService,
      {
        provide: CacheService,
        useValue: {
          checkInCache: jest.fn().mockReturnValue(Promise<null>),
          setToCache: jest.fn().mockReturnValue(Promise),
        },
      },
    ],
  })
    .useMocker(() => createMock())
    .compile();
  calculatorController =
    moduleRef.get<CalculatorController>(CalculatorController);
  calculatorService = moduleRef.get<CalculatorService>(CalculatorService);
  jest.clearAllMocks();
});

describe('Calculator Controller', () => {
  it('should be defined', () => {
    expect(calculatorController).toBeDefined();
  });
  it('should have all methods', () => {
    expect(calculatorController.getResult).toBeDefined();
    expect(calculatorController.getResult(calculatorStub().request)).toBe(
      typeof Promise,
    );
  });
});
typescript nestjs
1个回答
0
投票

不确定这是不是你想要的。

我像这样创建了新的缓存模块

./src/cache/cache.module.ts

import {  Module } from '@nestjs/common';
import { CacheModule as NestJsCacheModule } from '@nestjs/cache-manager'
import { ConfigModule } from '@nestjs/config';
import { redisStore } from 'cache-manager-redis-store';
import type { RedisClientOptions } from 'redis';

import config from '../common/configs/config';
import { ConfigService } from '@nestjs/config';
import {CacheManagerService} from './cache-manager.service';


@Module({
  imports: [
    ConfigModule.forFeature(config),
  
    NestJsCacheModule.registerAsync<Promise<RedisClientOptions>>({
      imports: [ConfigModule],
      isGlobal: true,
      useFactory: async (configService: ConfigService) => ({
        store: redisStore,
        url: configService.get('REDIS_URL'),
      }),
      inject: [ConfigService],
    }),

  ],
  providers: [CacheManagerService],
  exports: [CacheManagerService],
})
export class CacheModule {}

./src/cache/cache-manager.service

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

@Injectable()
export class CacheManagerService {
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  public async get(key: string): Promise<string> {
    return this.cacheManager.get(key);
  }

  /**
   * Sets a value in the cache.
   *
   * @param {string} key - The key under which to store the value.
   * @param {any} value - The value to store.
   * @param {number} [ttl] - The time-to-live in milliseconds for the cache entry. Optional.
   *
   * @returns {Promise<void>} A promise that resolves when the value has been set in the cache.
   */
  public async set(key: string, value: any, ttl?: number): Promise<void> {
    return this.cacheManager.set(key, value, ttl);
  }

  /**
   * Deletes a value from the cache.
   *
   * @param {string} key - The key under which the value is stored.
   *
   * @returns {Promise<void>} A promise that resolves when the value has been deleted from the cache.
   */
  public async del(key: string): Promise<void> {
    return this.cacheManager.del(key);
  }
}

然后将

CacheModule
导入到
app.module.ts
并随意在整个应用程序中使用
cache-manager-service

import { CacheManagerService } from '../cache/cache-manager.service';

package.json

    "@nestjs/cache-manager": "^2.1.1",
    "@nestjs/common": "10.1.0",
    "@nestjs/config": "3.0.0",
    "@nestjs/core": "10.1.0",
    "cache-manager": "^5.3.2",
    "cache-manager-redis-store": "^3.0.1",
© www.soinside.com 2019 - 2024. All rights reserved.