Ajoute un cache redis de 2h sur l'api /evaluate

pull/2722/head
Jérémy Rialland 2023-06-15 15:09:48 +02:00 committed by Jérémy Rialland
parent fa40aa8f0f
commit ccaaea2714
4 changed files with 134 additions and 14 deletions

View File

@ -36,6 +36,7 @@
"@sentry/tracing": "^7.55.2",
"got": "^13.0.0",
"ioredis": "^5.3.2",
"ioredis-mock": "^8.7.0",
"koa": "^2.14.2",
"koa-body": "^6.0.1",
"koa-static": "^5.0.0",
@ -46,6 +47,7 @@
"swagger-ui-dist": "^4.15.5"
},
"devDependencies": {
"@types/ioredis-mock": "^8.2.2",
"@types/koa": "^2.13.6",
"@types/koa-static": "^4.0.2",
"@types/koa__cors": "^4.0.0",

View File

@ -9,6 +9,7 @@ import { catchErrors } from './errors.js'
import openapi from './openapi.json' assert { type: 'json' }
import { plausibleMiddleware } from './plausible.js'
import { rateLimiterMiddleware } from './rate-limiter.js'
import { redisCacheMiddleware } from './redis-cache.js'
import { docRoutes } from './route/doc.js'
import { openapiRoutes } from './route/openapi.js'
import Sentry, { requestHandler, tracingMiddleWare } from './sentry.js'
@ -43,7 +44,13 @@ router.use('/api/v1', docRoutes(), openapiRoutes(openapi))
const apiRoutes = publicodesAPI(new Engine(rules))
router.use('/api/v1', plausibleMiddleware, rateLimiterMiddleware, apiRoutes)
router.use(
'/api/v1',
rateLimiterMiddleware,
redisCacheMiddleware(),
plausibleMiddleware,
apiRoutes
)
app.use(router.routes())
app.use(router.allowedMethods())

50
api/source/redis-cache.ts Normal file
View File

@ -0,0 +1,50 @@
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 2 hours
const CACHE_EXPIRE = 2 * 60 * 60
const redis =
process.env.NODE_ENV === 'production' && process.env.SCALINGO_REDIS_URL
? new Redis(process.env.SCALINGO_REDIS_URL, {
enableOfflineQueue: false,
})
: 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 = JSON.stringify(ctx.request.body)
const cachedResponse = await redis.get(cacheKey)
if (cachedResponse) {
ctx.body = JSON.parse(cachedResponse) as unknown
return
}
await next()
if (ctx.status === 200) {
await redis.set(
cacheKey,
JSON.stringify({ responseCachedAt: Date.now(), ...ctx.body }),
'EX',
CACHE_EXPIRE
)
}
})
return router.routes()
}

View File

@ -3579,7 +3579,14 @@ __metadata:
languageName: node
linkType: hard
"@ioredis/commands@npm:^1.1.1":
"@ioredis/as-callback@npm:^3.0.0":
version: 3.0.0
resolution: "@ioredis/as-callback@npm:3.0.0"
checksum: 2835e39631497fe4f8b07d95576abea165c9f7efef81e9e55c733588051ff4edcb31eeb59f36127923dae0cb1a8e21b4e27ee3ab79a065a0baeecf861c3bc0b1
languageName: node
linkType: hard
"@ioredis/commands@npm:^1.1.1, @ioredis/commands@npm:^1.2.0":
version: 1.2.0
resolution: "@ioredis/commands@npm:1.2.0"
checksum: 9b20225ba36ef3e5caf69b3c0720597c3016cc9b1e157f519ea388f621dd9037177f84cfe7e25c4c32dad7dd90c70ff9123cd411f747e053cf292193c9c461e2
@ -8863,7 +8870,16 @@ __metadata:
languageName: node
linkType: hard
"@types/formidable@npm:^2.0.4, @types/formidable@npm:^2.0.5":
"@types/formidable@npm:^2.0.4":
version: 2.0.6
resolution: "@types/formidable@npm:2.0.6"
dependencies:
"@types/node": "*"
checksum: d6be0ac12bf8dd2e4f8a022271ee6e501c7f6d7dd58d71c68497ca7da84bee1538d1a2a64a90b56dad557ddb291d48c5731206269e9ab53ed91264e68a4d1476
languageName: node
linkType: hard
"@types/formidable@npm:^2.0.5":
version: 2.0.5
resolution: "@types/formidable@npm:2.0.5"
dependencies:
@ -8970,6 +8986,15 @@ __metadata:
languageName: node
linkType: hard
"@types/ioredis-mock@npm:^8.2.2":
version: 8.2.2
resolution: "@types/ioredis-mock@npm:8.2.2"
dependencies:
ioredis: ">=5"
checksum: caf0fd904d84ec6da31cde540cd04a0619e20ea42f88f2b11758c7afd24a9b4213661589c74efb03e109ba24cbd90794e0ef34294c7e5f9fe0c033536509a83e
languageName: node
linkType: hard
"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1":
version: 2.0.4
resolution: "@types/istanbul-lib-coverage@npm:2.0.4"
@ -10277,6 +10302,7 @@ __metadata:
"@publicodes/api": ^1.0.0-beta.70
"@sentry/node": ^7.55.2
"@sentry/tracing": ^7.55.2
"@types/ioredis-mock": ^8.2.2
"@types/koa": ^2.13.6
"@types/koa-static": ^4.0.2
"@types/koa__cors": ^4.0.0
@ -10286,6 +10312,7 @@ __metadata:
chai-http: ^4.4.0
got: ^13.0.0
ioredis: ^5.3.2
ioredis-mock: ^8.7.0
koa: ^2.14.2
koa-body: ^6.0.1
koa-static: ^5.0.0
@ -15278,6 +15305,26 @@ __metadata:
languageName: node
linkType: hard
"fengari-interop@npm:^0.1.3":
version: 0.1.3
resolution: "fengari-interop@npm:0.1.3"
peerDependencies:
fengari: ^0.1.0
checksum: f483e0aedec3a0b49911ffd3207a55f73c861f95ef84fb7582deb45bc65afa2e7bf8f9fc3734563f6c106a438909f94059b5d08f5a7872ffcc3d45d260a3ee15
languageName: node
linkType: hard
"fengari@npm:^0.1.4":
version: 0.1.4
resolution: "fengari@npm:0.1.4"
dependencies:
readline-sync: ^1.4.9
sprintf-js: ^1.1.1
tmp: ^0.0.33
checksum: bd6b04f9738f9cbb58e3c80684a72bf6f7e74c902d26e4e812b1cfbd69c06da5ffb2a8a67a62ecd75603fc565b6b183c1b72be60f2e60c18aa487aad65b62196
languageName: node
linkType: hard
"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4":
version: 3.2.0
resolution: "fetch-blob@npm:3.2.0"
@ -17446,7 +17493,23 @@ __metadata:
languageName: node
linkType: hard
"ioredis@npm:^5.3.2":
"ioredis-mock@npm:^8.7.0":
version: 8.7.0
resolution: "ioredis-mock@npm:8.7.0"
dependencies:
"@ioredis/as-callback": ^3.0.0
"@ioredis/commands": ^1.2.0
fengari: ^0.1.4
fengari-interop: ^0.1.3
semver: ^7.3.8
peerDependencies:
"@types/ioredis-mock": ^8
ioredis: ^5
checksum: 46a4ee40b899e950569cdfa3f009b797fc5c5acbdc6b1784f8cdeb54ba781ed288b61c4c86c88760a02ea6a481e655660df0507096f93c66c2e8285f029ff8fd
languageName: node
linkType: hard
"ioredis@npm:>=5, ioredis@npm:^5.3.2":
version: 5.3.2
resolution: "ioredis@npm:5.3.2"
dependencies:
@ -22576,7 +22639,7 @@ __metadata:
languageName: node
linkType: hard
"qs@npm:^6.11.2":
"qs@npm:^6.11.2, qs@npm:^6.4.0":
version: 6.11.2
resolution: "qs@npm:6.11.2"
dependencies:
@ -22585,15 +22648,6 @@ __metadata:
languageName: node
linkType: hard
"qs@npm:^6.4.0":
version: 6.11.1
resolution: "qs@npm:6.11.1"
dependencies:
side-channel: ^1.0.4
checksum: 82ee78ef12a16f3372fae5b64f76f8aedecb000feea882bbff1af146c147f6eb66b08f9c3f34d7e076f28563586956318b9b2ca41141846cdd6d5ad6f241d52f
languageName: node
linkType: hard
"qs@npm:~6.5.2":
version: 6.5.3
resolution: "qs@npm:6.5.3"
@ -23360,6 +23414,13 @@ __metadata:
languageName: node
linkType: hard
"readline-sync@npm:^1.4.9":
version: 1.4.10
resolution: "readline-sync@npm:1.4.10"
checksum: 4dbd8925af028dc4cb1bb813f51ca3479035199aa5224886b560eec8e768ab27d7ebf11d69a67ed93d5a130b7c994f0bdb77796326e563cf928bbfd560e3747e
languageName: node
linkType: hard
"real-require@npm:^0.2.0":
version: 0.2.0
resolution: "real-require@npm:0.2.0"