Basic caching in node.js
So now we want to integrate into node. Again, I'll defer you to the docs of node_redis as to how to integrate with a node server. Let's assume your node server is already set up and you have a route called /books
. When you send a GET request to this route, it should return all of the books in our database.
router.get('/books', function(req, res, next) {
redis.get("books", function (err, reply) {
if (err || reply == null) {
console.log('key not found');
Book.find(function(err, books){
if(err){ return next(err); }
redis.set("books", JSON.stringify(books), redis.print);
console.log("setting key", books);
res.json(books);
});
} else {
console.log("key found", JSON.parse(reply));
res.json(JSON.parse(reply));
}
});
});
As you can see, we've wrapped our logic for interacting with the database in Redis logic. We first ask Redis if there is any value at the key "books". If there isn't, or we can't connect to Redis, we then query the database for the books. Once our query finishes, we then set the key "books" to a stringified version of our object, and finally return the object to the user.
Our first GET request to /books
looks like this. Note the time that the request took.
So now we have a value at the key "books" in Redis. Which means, if we resend this request, we shouldn't need to query the database for the list of books, we should be able to get it from Redis. Lets send that request again!
Nice! Note the request took MUCH less time this time around. Because we didn't have to query the database and we benefited from the constant lookup time of a key value system.
Now, let's try the same thing with an individual book. This time, we're going to use the Hash system in Redis to store a value for a key index under another key. Basically, we want to store the value for a book id under the key "book".
Here's the code we're going to use.
router.param('book', function(req, res, next, id) {
var query = Book.findById(id);
redis.hget("book", id, function (err, reply) {
if (err || reply == null) {
console.log('key not found');
query.exec(function (err, book){
if (err) { return next(err); }
if (!book) { return next(new Error('can\'t find book')); }
console.log('setting key', book);
redis.hset("book", id, JSON.stringify(book));
req.book = book;
return next();
});
} else {
console.log("key found", JSON.parse(reply));
req.book = JSON.parse(reply);
return next();
}
});
});
router.route('/books/:book')
.get(function(req, res, next) {
res.json(req.book);
});
Now we are using a hash to store our individual books. Let's request the book we found earlier when we requested all books.
Again, check out the time each request took. We didn't save as much time here since we were querying the database for a single id, but we saved time all the same.