diff options
| author | Ritesh Ghosh <[email protected]> | 2024-12-07 21:12:34 +0530 |
|---|---|---|
| committer | Ritesh Ghosh <[email protected]> | 2024-12-07 21:12:34 +0530 |
| commit | b7d036dbe29fcfa39c6573a0f02888093eb43d78 (patch) | |
| tree | 03541cdb97d45f439126cbadcd1505fb6a688b84 /src | |
| parent | db022185efd04d4382883de543d3f3399cd28a6b (diff) | |
| download | aniwatch-api-b7d036dbe29fcfa39c6573a0f02888093eb43d78.tar.xz aniwatch-api-b7d036dbe29fcfa39c6573a0f02888093eb43d78.zip | |
feat(cache): add `AniwatchAPICache` class to implement API caching layer
Diffstat (limited to 'src')
| -rw-r--r-- | src/config/cache.ts | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/config/cache.ts b/src/config/cache.ts new file mode 100644 index 0000000..6953fbc --- /dev/null +++ b/src/config/cache.ts @@ -0,0 +1,50 @@ +import { config } from "dotenv"; +import { Redis } from "ioredis"; + +config(); + +export class AniwatchAPICache { + private _client: Redis | null; + public isOptional: boolean = true; + + static DEFAULT_CACHE_EXPIRY_SECONDS = 60 as const; + static CACHE_EXPIRY_HEADER_NAME = "X-ANIWATCH-CACHE-EXPIRY" as const; + + constructor() { + const redisConnURL = process.env?.ANIWATCH_API_REDIS_CONN_URL; + this.isOptional = !Boolean(redisConnURL); + this._client = this.isOptional ? null : new Redis(String(redisConnURL)); + } + + set(key: string | Buffer, value: string | Buffer | number) { + if (this.isOptional) return; + return this._client?.set(key, value); + } + + get(key: string | Buffer) { + if (this.isOptional) return; + return this._client?.get(key); + } + + /** + * @param expirySeconds set to 60 by default + */ + async getOrSet<T>( + key: string | Buffer, + setCB: () => Promise<T>, + expirySeconds: number = AniwatchAPICache.DEFAULT_CACHE_EXPIRY_SECONDS + ) { + const cachedData = this.isOptional + ? null + : (await this._client?.get(key)) || null; + let data = JSON.parse(String(cachedData)) as T; + + if (!data) { + data = await setCB(); + await this._client?.set(key, JSON.stringify(data), "EX", expirySeconds); + } + return data; + } +} + +export const cache = new AniwatchAPICache(); |
