我想实现nestjs自定义缓存

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

在nsetjs默认的缓存机制所行没有提供足够的灵活性,因为你不能用注释指令routes/methods或类似的东西个人@Cache

我希望能够设置自定义TTL以及我不想隐藏每个route.May是它甚至是有意义的移动缓存,以服务水平为目的,目前还不能确定。

只是想知道你会怎么做,在一个更好的方式withing nestjs框架。只是缓存特定的路线或者服务方式。

typescript nestjs
1个回答
0
投票

最近,我开始一个缓存模块上工作NestJS运行到你做了同样的问题后。这可于@nestjs-plus/caching故宫虽然它没有准备好使用但我会在这里分享的拦截器定义。它依赖于混入模式能够每路线选择接受。

import { makeInjectableMixin } from '@nestjs-plus/common';
import {
  ExecutionContext,
  Inject,
  Injectable,
  NestInterceptor
} from '@nestjs/common';
import { forkJoin, Observable, of } from 'rxjs';
import { catchError, map, switchMap } from 'rxjs/operators';
import { Cache, CacheToken } from './cache';

@Injectable()
export abstract class CachingInterceptor implements NestInterceptor {
  protected abstract readonly options: CacheOptions;

  constructor(@Inject(CacheToken) private readonly cache: Cache) {}

  async intercept(
    context: ExecutionContext,
    call$: Observable<any>
  ): Promise<Observable<any>> {
    const http = context.switchToHttp();
    const request = http.getRequest();
    const key = this.options.getKey(request);

    const cached = await this.cache.get(key);
    if (cached != null) {
      return of(cached);
    }

    return call$.pipe(
      switchMap(result => {
        return forkJoin(
          of(result),
          this.cache.set(key, result, this.options.ttl)
        ).pipe(catchError(e => of(result)));
      }),
      map(([result, setOp]) => result)
    );
  }
}

export interface CacheOptions {
  ttl: number;
  getKey: (request) => string;
}

export const makeCacheInterceptor = (options: CacheOptions) => {
  return makeInjectableMixin('CachingInterceptor')(
    class extends CachingInterceptor {
      protected readonly options = options;
    }
  );
};

export interface Cache {
  get: (key: string) => Promise<any | null | undefined>;
  set: (key: string, data: any, ttl: number) => Promise<void>;
  del: (key: string) => Promise<void>;
}

export const CacheToken = Symbol('CacheToken');

该模式允许高速缓存的每条路线在控制器中具有不同的TTL或提取从传入的请求的高速缓存项的方法的应用。

@Get()
  @UseInterceptors(
    makeCacheInterceptor({
      getKey: () => '42' // could be req url, query params, etc,
      ttl: 5,
    }),
  )
  getHello(): string {
    return this.appService.getHello();
  }

从这里唯一缺少的东西(我工作的库)是一套灵活的缓存实现的,如内存,Redis的,DB等我计划与缓存管理库集成本周填补这一空白(它是相同的缓存供应商,鸟巢使用默认的缓存实现)。随意以此为基础创建自己还是敬请期待时@nestjs-plus/caching是随时可以使用。当我发布一个生产准备的版本,我会在本周晚些时候更新这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.