45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import { Injectable, Inject } from '@nestjs/common';
|
|
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
|
import { Cache } from 'cache-manager';
|
|
import { ConfigService } from '@nestjs/config';
|
|
|
|
@Injectable()
|
|
export class CacheService {
|
|
constructor(
|
|
@Inject(CACHE_MANAGER) private cacheManager: Cache,
|
|
private configService: ConfigService,
|
|
) {}
|
|
|
|
async get<T>(key: string): Promise<T | undefined> {
|
|
return this.cacheManager.get<T>(key);
|
|
}
|
|
|
|
async set(key: string, value: unknown, ttl?: number): Promise<void> {
|
|
await this.cacheManager.set(key, value, ttl);
|
|
}
|
|
|
|
private buildKey(...parts: string[]): string {
|
|
return parts.join(':');
|
|
}
|
|
|
|
async getOrFetch<T>(
|
|
keyPrefix: string,
|
|
keyParts: string[],
|
|
fetchFn: () => Promise<T>,
|
|
ttlConfigKey: string,
|
|
): Promise<{ data: T; fromCache: boolean; cachedAt: string | null }> {
|
|
const key = this.buildKey(keyPrefix, ...keyParts);
|
|
const ttl = this.configService.get<number>(`app.cache.${ttlConfigKey}`, 900);
|
|
|
|
const cached = await this.get<T>(key);
|
|
if (cached !== undefined) {
|
|
return { data: cached, fromCache: true, cachedAt: null };
|
|
}
|
|
|
|
const data = await fetchFn();
|
|
await this.set(key, data, ttl);
|
|
|
|
return { data, fromCache: false, cachedAt: new Date().toISOString() };
|
|
}
|
|
}
|