How to implement Redis with Node.js and Express

Sukhada Gholba
4 min readMay 5, 2019
Image source: Redis Wikipedia Image.

If you are a developer and you haven’t heard of redis then this is a good place to start. By the end of this article you will hopefully fall in love with redis and wonder why you have never used it before. Redis was born based on a conversation between redis creator Salvatore Sanfilippo and Paul Graham.

“A little known story about how @paulg, writing a comment in the newborn Hacker News, inspired the creation of Redis. At some point he wrote that in certain Lisp programs he wrote there was this pattern of just storing data in memory, logging on disk what it was stored in memory.

When the application would be restarted, reading back the log would recreate the in memory data structures. I thought that it was cool, and that databases themselves could be that way instead of using the programming language data structures without a networked API

However I quickly forgot about this idea and continued with my stuff. At some point a year or so later I was facing with a very write heavy application, and at that point it made sense to try doing exactly that. Ideas exchange is a key part of building things” — Salvatore Sanfilippo aka antirez https://twitter.com/antirez/status/1110468354542919681

Redis is used as a cache, if the data you’re looking for is present in your cache, you don’t have to make a request to your database which means you save time and serve data faster to your client.

Now, if you don’t know what caching is then it can be best described as a process of storing data in a temporary (but fast!) storage area, so that future requests for that data can be served faster. So redis is a cache that stores data as a key-value pair.

So how do you setup redis to cache data and make future requests faster? You will need to download redis locally from https://redis.io/download. On Heroku you can use the Heroku Redis add-on.

Follow the instructions for download and test your redis server by using the command redis-server which should display the redis logo and the message ‘Ready to accept connections’. To get redis working on your node app, install redis and ioredis packages.

npm install redis
npm install ioredis // ioredis is Redis client for Node.js

Once you have redis and ioredis installed, let’s setup redis on your node app

const express = require('express');
const router = express.Router();
const db = require('../../data/helpers/repDb');
//production redis url
let redis_url = process.env.REDIS_URL;
if (process.env.ENVIRONMENT === 'development') {
require('dotenv').config();
redis_url = "redis://127.0.0.1";
}
//redis setup
let client = require('redis').createClient(redis_url);
let Redis = require('ioredis');
let redis = new Redis(redis_url);
//sample endpoint to GET representative deatilsrouter.get('/alldetails', (req,res) => {
const uid = req.body.uid; //uid is unique identifier
//check if rep details are present in cache client.get(uid, (error, rep)=> {
if(error){
res.status(500).json({error: error});
return;
}
if(rep){
//JSON objects need to be parsed after reading from redis, since it is stringified before being stored into cache

res.status(200).json(JSON.parse(rep));
}
else{
//if data not present in cache, make a request to db
const request = db.getDetails(uid);
request.then(response_data => {
if(response_data.length == 0) {
res.status(400).json({ error: "The representative with the specified uid does not exist" });
}
else {
res.status(200).json(response_data);
//cache data received from db
client.set(uid, JSON.stringify(response_data),(error, result)=> {
if(error){
res.status(500).json({ error: error});
}})
} //end of inner else
}) //end of .then
.catch(err => {
res.status(500).json({ err: err.message });
})
} //end of outer else
}) //end of clinet.get
});

When you make a GET request to get representative details, you first check if the details are present in your cache by using client.get(). If the rep with the specified uid is present in your cache, you just return the request from cache and never make a request to your database. The runtime complexity for client.get() is O(1).

But, if the requested rep with the specified uid is not present in cache, first retrieve it from the database (which is a more time intensive request), then before continuing on, use client.set() which stores the rep details in cache using the uid as the key and the rep details as the value associated with the key. It is stringified before being stored in redis, hence, JSON objects need to be parsed after reading from cache. The runtime complexity for client.set() is O(1).

If you delete or update the rep details from your database make sure to delete or set updated details in your cache or you will end up returning outdated details the next time there is a GET request.

// delete from endpoint, then remove cached key / value pairrouter.delete('/:id', (req, res) => { 
const id = req.params.id;
const uid = req.body.uid;
const request = db.remove(id);

request.then(response_data => {
client.del(uid, (error, result)=> {
if(error){
res.status(500).json({error: error});
return;
}
if(result){
res.status(200).json(response_data);
}
})
})
.catch(error => {
res.status(500).json({error: "Failed to delete user"});
})
});

client.del() removes an existing key-value pair from the cache if it exists, a key is ignored if it does not exist. To update a key / value pair, one just calls a new client.set() which replaces an existing key / value pair.

This is how simple it is to setup redis on your Node/Express app. I hope you enjoyed this easy redis setup guide.

Cache, Cache and Cache more data to improve performance :-)

Here is a link to a github repo to a project I worked with a team of 5 developers and used redis to cache data. https://github.com/Lambda-School-Labs/labs10-webchat/blob/master/routes/reprensentatives/repRoutes.js

--

--

Sukhada Gholba

I love developing apps in Javascript, Node, Python, React, SQL and NoSQL. In my free time I am an avid reader, I like cooking, traveling & history.