Last Updated on August 4, 2021 by Amarjit Singh
Node JS offers to build fast and scalable applications. However, sometimes an API built has to do some heavy computation or fetch data from a distant server. Which affects the response time (TTFB) of the API very badly.
Therefore, If your app returns the same data for some particular requests by different clients then you can cache the response of such endpoints by using middleware.
1. Install the node-cahce NPM package
To install this package, use the following command.
npm install --save node-cache
2. Import the package and Initialize it
Add the following lines in your “server.js” or “index.js” file. This is the file where you’ve initialized the ExpressJs app instance.
const NodeCache = require( "node-cache" );
const myCache = new NodeCache( { stdTTL: 300, checkperiod: 310 } );
In the second line, we’ve initialized stdTTL to 300 seconds which means the cache will be valid for 5 minutes.
3. Create middleware for the routes for which you want to implement caching
Following is an example of an empty middleware function.
app.use(function (req, res, next) {
});
4. Add the caching code in the middleware
In this middleware, First, we’ll check if the request method is “GET” or not because our objective is to only cache the GET requests.
So if the request method is not “GET” then we’ll call the “next()” method followed by the “return” keyword.
But if the request method is “GET”, then we’ll check if we have any cache is saved for the current requested URL. If yes then we’ll return the response from the cache and add a header “X-Proxy-Cache” with the value “HIT”. Otherwise, we’ll overwrite the “send” method of the request object with a function that will save the cache for headers and the body of the current request. After saving cache, we’ll add a header “X-Proxy-Cache” with the value “MISS” and then we’ll call the original send method of the request object, and then finally we’ll call the “next()” method followed by the “return” keyword.
After adding all of this code our middleware will look like the following middleware.
app.use(function (req, res, next) {
if (req.method != 'GET') {
return next();
}
var cachedReponse = myCache.get(req.url);
if (cachedReponse) {
res.header(cachedReponse.headers);
res.header('X-Proxy-Cache', 'HIT');
return res.send(cachedReponse.body);
} else {
res.originalSend = res.send;
res.send = (body) => {
myCache.set(req.url, {
'headers' : res.getHeaders(),
'body' : body
});
res.header('X-Proxy-Cache', 'MISS');
res.originalSend(body);
};
return next();
}
});
Conclusion
Now all the routes after this middleware will be cached for 5 minutes.
Here is an example of a full server.js file
const express = require('express');
const request = require('request');
const NodeCache = require( "node-cache" );
const myCache = new NodeCache( { stdTTL: 300, checkperiod: 310 } );
const app = express();
const port = 8000;
app.get('/greetings', function(req, res, next) { // This route won't be cached
res.send('Helloworld!');
});
// ======================================== Caching Middleware ===========================
app.use(function (req, res, next) {
if (req.method != 'GET') {
return next();
}
var cachedReponse = myCache.get(req.url);
if (cachedReponse) {
res.header(cachedReponse.headers);
res.header('X-Proxy-Cache', 'HIT');
return res.send(cachedReponse.body);
} else {
res.originalSend = res.send;
res.send = (body) => {
myCache.set(req.url, {
'headers' : res.getHeaders(),
'body' : body
});
res.header('X-Proxy-Cache', 'MISS');
res.originalSend(body);
};
return next();
}
});
// =================== All the routes after this middleware will be cached ================
app.get('/todos/:todo_id?', (req, res) => { // This route will be cached
var request = require('request');
var apiUrl = 'https://jsonplaceholder.typicode.com/todos' + (req.params.todo_id ? '/'+req.params.todo_id : '');
request(apiUrl, function (error, response, body) {
if (!error && response.statusCode === 200) {
res.send(body);
}
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
Note: If you have any trouble understanding anything from this article feel free to drop a comment. I’ll be happy to help.
how to disable cache for 404?
app.use(function(req, res, next){
res.status(404);
res.render(‘404’);
});
Do this
if (res.statusCode < 200 || res.statusCode >= 300) {
// Don't save cache
}