66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { FastifyInstance } from 'fastify';
|
|
import fp from 'fastify-plugin';
|
|
import Caching from '@fastify/caching';
|
|
|
|
declare module 'fastify' {
|
|
interface FastifyContextConfig {
|
|
serverCache?: {
|
|
key?: string;
|
|
ttl: number;
|
|
};
|
|
}
|
|
}
|
|
|
|
export default fp(async function (fastify: FastifyInstance) {
|
|
|
|
fastify.register(Caching,{
|
|
expiresIn: 10000,
|
|
privacy: Caching.privacy.PUBLIC,
|
|
// TODO: default is a mem cache, should use redis cache for prod, for example
|
|
})
|
|
.addHook('onRoute', (routeOptions) => {
|
|
const { config } = routeOptions;
|
|
|
|
if (config?.serverCache) {
|
|
|
|
const { key, ttl = 10000 } = config.serverCache;
|
|
|
|
// set or add our handler to the route preHandler hook
|
|
Object.entries({
|
|
preHandler: (request, reply, done) => {
|
|
fastify.cache.get(key || encodeURIComponent(request.raw.url), (err, cached) => {
|
|
if (err) {
|
|
// TODO: handle error
|
|
done();
|
|
return;
|
|
}
|
|
if (cached?.item) {
|
|
console.log('from cache');
|
|
reply.send(cached.item);
|
|
} else {
|
|
console.log('getting fresh data');
|
|
}
|
|
|
|
done();
|
|
});
|
|
|
|
return reply;
|
|
},
|
|
onSend: (request, _reply, payload, done) => {
|
|
fastify.cache.set(key || encodeURIComponent(request.raw.url), payload, ttl, () => {done();});
|
|
},
|
|
}).forEach(([hook, handler]) => {
|
|
if (!routeOptions[hook]) {
|
|
routeOptions[hook] = [handler]
|
|
return
|
|
}
|
|
if (Array.isArray(routeOptions[hook])) {
|
|
routeOptions[hook].push(handler)
|
|
return
|
|
}
|
|
routeOptions[hook] = [routeOptions[hook], handler]
|
|
})
|
|
}
|
|
})
|
|
});
|