Skip to content

Instantly share code, notes, and snippets.

@hiepxanh
Created October 27, 2022 02:26
Show Gist options
  • Save hiepxanh/9bb1d4845e48826c55c69bd52d75ad6f to your computer and use it in GitHub Desktop.
Save hiepxanh/9bb1d4845e48826c55c69bd52d75ad6f to your computer and use it in GitHub Desktop.
nestjs-custom-cache.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from "@nestjs/common";
import { CACHE_MANAGER, Inject } from "@nestjs/common";
import { Cache } from "cache-manager";
import {
from,
map,
Observable,
of,
mergeMap,
switchMap,
firstValueFrom,
forkJoin,
} from "rxjs";
@Injectable()
export class CustomCacheInterceptor implements NestInterceptor {
constructor(@Inject(CACHE_MANAGER) private cacheService: Cache) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
// check if data is in cache:
const url = context.switchToHttp().getRequest().url;
const CACHE_KEY = `URL__${url}`;
// console.log(
// "your context",
// context.switchToHttp().getRequest().url,
// CACHE_KEY
// );
const cacheResult$ = from(this.cacheService.get<any>(CACHE_KEY));
const cacheExpire$ = from(this.cacheService.get<any>(CACHE_KEY + '_expire'));
return forkJoin([cacheResult$, cacheExpire$]).pipe(
switchMap(([cacheResult, cacheExpire]) => {
if (cacheResult && cacheExpire && Date.now() < +cacheExpire) {
return this.checkCache({cacheResult, CACHE_KEY, shouldRender: true}, next, context);
} else {
return this.checkCache({cacheResult, CACHE_KEY, shouldRender: false}, next, context);
}
})
)
}
checkCache({cacheResult, CACHE_KEY, shouldRender}, next, context) {
// console.log('should render or not?', shouldRender, cacheResult )
if (shouldRender) {
// console.log("nice, we have cache now, response the cache instead");
context.switchToHttp().getResponse().send(cacheResult);
return of(cacheResult);
} else {
// if (cacheResult) {
// console.log("cache here but invalid, render and save cache");
// } else {
// console.log("we dont have cache, render and save cache");
// }
return next.handle().pipe(
map((resData) => {
this.cacheService.set(CACHE_KEY, resData, { ttl: 0 });
this.cacheService.set(CACHE_KEY + '_expire', new Date().getTime() + 10 * 1000, { ttl: 0 });
console.log("cached res data:", resData);
return resData;
})
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment