You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+120Lines changed: 120 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,6 +80,126 @@ service.start(3000)
80
80
}]
81
81
}
82
82
```
83
+
## Gateway level caching
84
+
### Why?
85
+
> Because `caching` is the last mile for low latency distributed systems!
86
+
87
+
Enabling proper caching strategies at gateway level will drastically reduce the latency of your system,
88
+
as it reduces network round-trips and remote services processing.
89
+
We are talking here about improvements in response times from `X ms` to `~2ms`, as an example.
90
+
91
+
### Setting up gateway level cache available for all services
92
+
#### Single node cache (memory):
93
+
```js
94
+
// cache middleware
95
+
constcache=require('http-cache-middleware')()
96
+
// enable http cache middleware
97
+
constgateway=require('fast-gateway')
98
+
constserver=gateway({
99
+
middlewares: [cache],
100
+
routes: [...]
101
+
})
102
+
```
103
+
> Memory storage is recommended if there is only one gateway instance and you are not afraid of losing cache data.
104
+
105
+
#### Multi nodes cache (redis):
106
+
```js
107
+
// redis setup
108
+
constCacheManager=require('cache-manager')
109
+
constredisStore=require('cache-manager-ioredis')
110
+
constredisCache=CacheManager.caching({
111
+
store: redisStore,
112
+
db:0,
113
+
host:'localhost',
114
+
port:6379,
115
+
ttl:30
116
+
})
117
+
118
+
// cache middleware
119
+
constcache=require('http-cache-middleware')({
120
+
stores: [redisCache]
121
+
})
122
+
123
+
// enable http cache middleware
124
+
constgateway=require('fast-gateway')
125
+
constserver=gateway({
126
+
middlewares: [cache],
127
+
routes: [...]
128
+
})
129
+
```
130
+
> Required if there are more than one gateway instances
131
+
132
+
### Enabling cache for service endpoints
133
+
Although API Gateway level cache aims as a centralized cache for all services behind the wall, are the services
134
+
the ones who indicate the responses to be cached and for how long.
135
+
136
+
Cache entries will be created for all remote responses coming with the `x-cache-timeout` header:
137
+
```js
138
+
res.setHeader('x-cache-timeout', '1 hour')
139
+
```
140
+
> Here we use the [`ms`](`https://www.npmjs.com/package/ms`) package to convert timeout to seconds. Please note that `millisecond` unit is not supported!
141
+
142
+
Example on remote service using `restana`:
143
+
```js
144
+
service.get('/numbers', (req, res) => {
145
+
res.setHeader('x-cache-timeout', '1 hour')
146
+
147
+
res.send([
148
+
1, 2, 3
149
+
])
150
+
})
151
+
```
152
+
153
+
### Invalidating cache
154
+
> Let's face it, gateway level cache invalidation was complex..., until now!
155
+
156
+
Remote services can also expire cache entries on demand, i.e: when the data state changes. Here we use the `x-cache-expire` header to indicate the gateway cache entries to expire using a matching pattern:
157
+
```js
158
+
res.setHeader('x-cache-expire', '*/numbers')
159
+
```
160
+
> Here we use the [`matcher`](`https://www.npmjs.com/package/matcher`) package for matching patterns evaluation.
161
+
162
+
Example on remote service using `restana`:
163
+
```js
164
+
service.patch('/numbers', (req, res) => {
165
+
res.setHeader('x-cache-expire', '*/numbers')
166
+
167
+
// ...
168
+
res.send(200)
169
+
})
170
+
```
171
+
172
+
### Custom cache keys
173
+
Cache keys are generated using: `req.method + req.url`, however, for indexing/segmenting requirements it makes sense to allow cache keys extensions.
174
+
Unfortunately, this feature can't be implemented at remote service level, because the gateway needs to know the entire lookup key when a request
175
+
reaches the gateway.
176
+
177
+
For doing this, we simply recommend using middlewares on the service configuration:
178
+
```js
179
+
routes: [{
180
+
prefix:'/users',
181
+
target:'http://localhost:3000',
182
+
middlewares: [(req, res, next) => {
183
+
req.cacheAppendKey= (req) =>req.user.id// here cache key will be: req.method + req.url + req.user.id
184
+
returnnext()
185
+
}]
186
+
}]
187
+
```
188
+
> In this example we also distinguish cache entries by `user.id`, very common case!
189
+
190
+
### Disable cache for custom endpoints
191
+
You can also disable cache checks for certain requests programmatically:
0 commit comments