Assist_Design/apps/bff/src/common/cache/cache.service.ts

62 lines
1.5 KiB
TypeScript
Raw Normal View History

2025-08-21 15:24:40 +09:00
import { Inject, Injectable, Logger } from '@nestjs/common';
import Redis from 'ioredis';
@Injectable()
2025-08-21 15:24:40 +09:00
export class CacheService {
private readonly logger = new Logger(CacheService.name);
2025-08-21 15:24:40 +09:00
constructor(
@Inject('REDIS_CLIENT') private readonly redis: Redis,
) {}
async get<T>(key: string): Promise<T | null> {
const value = await this.redis.get(key);
2025-08-21 15:24:40 +09:00
return value ? (JSON.parse(value) as T) : null;
}
2025-08-21 15:24:40 +09:00
async set(key: string, value: unknown, ttlSeconds?: number): Promise<void> {
const serialized = JSON.stringify(value);
if (ttlSeconds) {
await this.redis.setex(key, ttlSeconds, serialized);
} else {
await this.redis.set(key, serialized);
}
}
async del(key: string): Promise<void> {
await this.redis.del(key);
}
async delPattern(pattern: string): Promise<void> {
const keys = await this.redis.keys(pattern);
if (keys.length > 0) {
await this.redis.del(...keys);
}
}
async exists(key: string): Promise<boolean> {
return (await this.redis.exists(key)) === 1;
}
buildKey(prefix: string, userId: string, ...parts: string[]): string {
return [prefix, userId, ...parts].join(':');
}
async getOrSet<T>(
key: string,
fetcher: () => Promise<T>,
ttlSeconds: number = 300,
): Promise<T> {
const cached = await this.get<T>(key);
if (cached !== null) {
return cached;
}
const fresh = await fetcher();
await this.set(key, fresh, ttlSeconds);
return fresh;
}
}
2025-08-21 15:24:40 +09:00