Skip to content

Commit bf99b23

Browse files
Change cache to a server decorator (#5)
1 parent 4a59503 commit bf99b23

File tree

3 files changed

+56
-43
lines changed

3 files changed

+56
-43
lines changed

.eslintrc.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"comma-dangle": ["error", "always-multiline"],
88
"eqeqeq": "error",
99
"no-extra-semi": "error",
10-
"object-curly-spacing": ["error", "never"]
10+
"object-curly-spacing": ["error", "never"],
11+
"space-before-function-paren": [
12+
"error",
13+
{"anonymous": "always", "named": "never", "asyncArrow": "always"}
14+
]
1115
}
1216
}

index.js

+41-42
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,17 @@ const Keyv = require('keyv')
55
const BPromise = require('bluebird')
66
const crypto = require('crypto')
77

8-
const cache = new Keyv()
9-
108
const CACHEABLE_METHODS = ['GET']
119
const INTERVAL = 200
1210
const X_RESPONSE_CACHE = 'x-response-cache'
1311
const X_RESPONSE_CACHE_HIT = 'hit'
1412
const X_RESPONSE_CACHE_MISS = 'miss'
1513

16-
const isCacheableRequest = (req) => {
14+
function isCacheableRequest(req) {
1715
return CACHEABLE_METHODS.includes(req.raw.method)
1816
}
1917

20-
const buildCacheKey = (req, {headers}) => {
18+
function buildCacheKey(req, {headers}) {
2119
const {url, headers: requestHeaders} = req.raw
2220
const additionalCondition = headers.reduce((acc, header) => {
2321
return `${acc}__${header}:${requestHeaders[header] || ''}`
@@ -29,7 +27,7 @@ const buildCacheKey = (req, {headers}) => {
2927
return key
3028
}
3129

32-
const waitForCacheFulfilled = async (key, timeout) => {
30+
async function waitForCacheFulfilled(cache, key, timeout) {
3331
let cachedString = await cache.get(key)
3432
let waitedFor = 0
3533

@@ -46,54 +44,53 @@ const waitForCacheFulfilled = async (key, timeout) => {
4644
return cachedString
4745
}
4846

49-
const createOnRequestHandler = ({
50-
ttl,
51-
additionalCondition: {headers},
52-
}) => async (req, res) => {
53-
if (!isCacheableRequest(req)) {
54-
return
55-
}
47+
function createOnRequestHandler({ttl, additionalCondition: {headers}}) {
48+
return async function handler(req, res) {
49+
if (!isCacheableRequest(req)) {
50+
return
51+
}
5652

57-
const key = buildCacheKey(req, {headers})
58-
const requestKey = `${key}__requested`
59-
const isRequestExisted = await cache.get(requestKey)
53+
const cache = this.responseCache
54+
const key = buildCacheKey(req, {headers})
55+
const requestKey = `${key}__requested`
56+
const isRequestExisted = await cache.get(requestKey)
6057

61-
if (isRequestExisted) {
62-
const cachedString = await waitForCacheFulfilled(key, ttl)
58+
if (isRequestExisted) {
59+
const cachedString = await waitForCacheFulfilled(cache, key, ttl)
6360

64-
if (cachedString) {
65-
const cached = JSON.parse(cachedString)
66-
res.header(X_RESPONSE_CACHE, X_RESPONSE_CACHE_HIT)
61+
if (cachedString) {
62+
const cached = JSON.parse(cachedString)
63+
res.header(X_RESPONSE_CACHE, X_RESPONSE_CACHE_HIT)
6764

68-
return res.code(cached.statusCode).send(cached.payload)
65+
return res.code(cached.statusCode).send(cached.payload)
66+
} else {
67+
res.header(X_RESPONSE_CACHE, X_RESPONSE_CACHE_MISS)
68+
}
6969
} else {
70+
await cache.set(requestKey, 'cached', ttl)
7071
res.header(X_RESPONSE_CACHE, X_RESPONSE_CACHE_MISS)
7172
}
72-
} else {
73-
await cache.set(requestKey, 'cached', ttl)
74-
res.header(X_RESPONSE_CACHE, X_RESPONSE_CACHE_MISS)
7573
}
7674
}
7775

78-
const createOnSendHandler = ({ttl, additionalCondition: {headers}}) => async (
79-
req,
80-
res,
81-
payload,
82-
) => {
83-
if (!isCacheableRequest(req)) {
84-
return
85-
}
86-
87-
const key = buildCacheKey(req, {headers})
76+
function createOnSendHandler({ttl, additionalCondition: {headers}}) {
77+
return async function handler(req, res, payload) {
78+
if (!isCacheableRequest(req)) {
79+
return
80+
}
8881

89-
await cache.set(
90-
key,
91-
JSON.stringify({
92-
statusCode: res.statusCode,
93-
payload,
94-
}),
95-
ttl,
96-
)
82+
const cache = this.responseCache
83+
const key = buildCacheKey(req, {headers})
84+
85+
await cache.set(
86+
key,
87+
JSON.stringify({
88+
statusCode: res.statusCode,
89+
payload,
90+
}),
91+
ttl,
92+
)
93+
}
9794
}
9895

9996
const responseCachingPlugin = (
@@ -103,7 +100,9 @@ const responseCachingPlugin = (
103100
) => {
104101
const headers = additionalCondition.headers || []
105102
const opts = {ttl, additionalCondition: {headers}}
103+
const responseCache = new Keyv()
106104

105+
instance.decorate('responseCache', responseCache)
107106
instance.addHook('onRequest', createOnRequestHandler(opts))
108107
instance.addHook('onSend', createOnSendHandler(opts))
109108

index.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ const BPromise = require('bluebird')
88

99
const plugin = require('./index.js')
1010

11+
test('should decorate cache to fastify instance', (t) => {
12+
t.plan(3)
13+
const instance = fastify()
14+
instance.register(plugin).ready(() => {
15+
t.ok(instance.responseCache)
16+
t.ok(instance.responseCache.set)
17+
t.ok(instance.responseCache.get)
18+
})
19+
})
20+
1121
test('should cache the cacheable request', (t) => {
1222
t.plan(6)
1323
const instance = fastify()

0 commit comments

Comments
 (0)