mon-entreprise/api/source/redis-cache.ts

59 lines
1.3 KiB
TypeScript

import { createHash } from 'crypto'
import Router from '@koa/router'
import IORedis from 'ioredis'
import IORedisMock from 'ioredis-mock'
import { koaBody } from 'koa-body'
const Redis = IORedis.default
const RedisMock = IORedisMock.default
// cache expires in 12 hours (in seconds)
const CACHE_EXPIRE = 12 * 60 * 60
const redis =
process.env.NODE_ENV === 'production' && process.env.SCALINGO_REDIS_URL
? new Redis(process.env.SCALINGO_REDIS_URL, {
enableOfflineQueue: false,
keyPrefix: 'cache',
})
: new RedisMock()
export const redisCacheMiddleware = () => {
const router = new Router()
router.post('/evaluate', koaBody(), async (ctx, next) => {
if (!redis || !ctx.request.body) {
await next()
return
}
const cacheKey = createHash('sha1')
.update(JSON.stringify(ctx.request.body))
.digest('base64')
const cachedResponse = await redis.get(cacheKey)
if (cachedResponse) {
ctx.body = JSON.parse(cachedResponse) as unknown
return
}
await next()
if (ctx.status === 200) {
const responseCachedAt = Date.now()
const cacheExpiresAt = responseCachedAt + CACHE_EXPIRE * 1000
await redis.set(
cacheKey,
JSON.stringify({ responseCachedAt, cacheExpiresAt, ...ctx.body }),
'EX',
CACHE_EXPIRE
)
}
})
return router.routes()
}