Usage
Injecting the service
import { Injectable } from '@nestjs/common';
import { Cache } from '@o2s/framework/modules';
@Injectable()
export class MyService {
constructor(private readonly cacheService: Cache.Service) {}
}
Cache-aside pattern
The standard pattern used throughout the framework:
async getData(id: string): Promise<Data> {
const key = `data-${id}`;
const cached = await this.cacheService.get(key);
if (cached) {
return JSON.parse(cached);
}
const data = await this.fetchFromSource(id);
await this.cacheService.set(key, JSON.stringify(data));
return data;
}
RxJS pattern (used in CMS)
import { from, of } from 'rxjs';
import { mergeMap, map } from 'rxjs/operators';
private getCachedData<T>(key: string, fetchData: () => Observable<T>): Observable<T> {
return from(this.cacheService.get(key)).pipe(
mergeMap((cached) => {
if (cached) return of(JSON.parse(cached));
return fetchData().pipe(
map((data) => {
this.cacheService.set(key, JSON.stringify(data));
return data;
}),
);
}),
);
}
Cache key patterns
// CMS content
`component-${id}-${locale}`
`page-${id}-${locale}`
`app-config-${locale}`
// Custom data
`user-${userId}-profile`
`product-${productId}-details`
Conventions:
- Use hyphens as separators
- Include identifiers (ID, locale)
- Use descriptive prefixes
Serialization
// Simple objects
await this.cacheService.set(key, JSON.stringify(data));
const parsed = JSON.parse(await this.cacheService.get(key));
// Objects with circular references (use flatted)
import { stringify, parse } from 'flatted';
await this.cacheService.set(key, stringify(data));
const parsed = parse(await this.cacheService.get(key));
Cache invalidation
async updateData(id: string, newData: Data): Promise<void> {
await this.repository.update(id, newData);
await this.cacheService.del(`data-${id}`);
}
Debugging
redis-cli KEYS * # List all keys
redis-cli GET component-123-en # Get specific key
redis-cli TTL component-123-en # Check TTL
redis-cli DBSIZE # Count keys