nsetjs 中的默认缓存机制没有提供足够的灵 active ,因为您无法注释个人 routes/methods使用 @Cache
指令或类似指令。
我希望能够设置自定义 ttl 以及我不想缓存每条路由。可能为此目的将缓存移动到服务级别甚至是有意义的,但还不确定。
只是想知道如何使用 nestjs 框架以更好的方式做到这一点。只是为了缓存特定的路由或服务方法。
最佳答案
在遇到与您相同的问题后,我最近开始为 NestJS 开发一个缓存模块。它在 @nestjs-plus/caching
的 npm 上可用,虽然它还没有完全准备好使用,但我将在这里分享拦截器定义。它依赖于 mixin 模式来接收每个路由选项。
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');
此模式允许在 Controller 中使用不同的 TTL 或从传入请求中提取缓存键的方法对每个路由进行缓存。
@Get()
@UseInterceptors(
makeCacheInterceptor({
getKey: () => '42' // could be req url, query params, etc,
ttl: 5,
}),
)
getHello(): string {
return this.appService.getHello();
}
这里(以及我正在处理的库)唯一缺少的是一组灵活的缓存实现,例如内存、redis、数据库等。我计划与缓存管理器库集成以填补这一空白本周(它与 Nest 用于默认缓存实现的缓存提供程序相同)。随意使用它作为创建自己的基础,或者在 @nestjs-plus/caching
准备好使用时继续关注。我将在本周晚些时候发布生产就绪版本时更新这个问题。
https://stackoverflow.com/questions/54508534/
相关文章:
angularjs - 使用 ui-sref 和 $state.go 在新标签页中打开
ruby-on-rails - 如何将数组作为绑定(bind)变量传递给 Rails/ActiveR
amazon-web-services - 我可以使用 boto 将 "ok_action"添加到现
node.js - Express Session cookie 未保存在 Chrome 中?
firebase - 为什么我的 Xamarin.iOS 应用程序没有收到来自 Google Fir
visual-studio-code - 进行文本搜索时如何防止水平滚动?
pandas - 重新采样 TimeSeries 时无法导入名称 'NaT'
r - 编辑 stargazer 源代码——保存的编辑不会呈现为 pdf