DEV Community

Saar Amrani
Saar Amrani

Posted on

Implement caching in Node.js with Redis

Caching is a simple mechanism that can make your API respond faster to a request that is repetitive.

Let's describe our problem:
We have a simple API that scrapes some data from a certain site and performs some heavy calculations on that data.
Our API response is slow - and this is not great for our users.
We know that this specific request may be received many times and that the information in our scraped site will only update every hour.

Our solution:
Caching!
We can cache our first response for the next hour and avoid doing those slow calculations over and over again.
Redis is very fast in memory data store that is perfect for this kind of task.

Implementation:
I will assume that you have Redis installed on your machine - if you don't, the Redis docs are very easy and simple to understand.
First of all lets initiate our app with express

//index.js
const express = require("express");

const app = express();

app.get("/heavy-task",(req, res) => {
  const { searchTerm } = req.query;

  const result = heavyTask(searchTerm);

  res.status(200).json({ result });
});

app.listen(PORT, () => {
  console.log("Server is listening on port " + PORT);
});
Enter fullscreen mode Exit fullscreen mode

Now let's install our Redis client to use Redis in our app - I'll be using ioredis.
We will initiate our client in a different file called cache.js

//cache.js

const Redis = require("ioredis");

const redisClient = new Redis();

redisClient.on("connect", () => {
  console.log("Redis connected");
});

redisClient.on("error", (err) => {
  console.log("Redis error", err);
})


module.exports = redisClient;
Enter fullscreen mode Exit fullscreen mode

Let's import our redisClient to the index.js to use it on our handler.
We will use the SETEX method which accepts our key for the data store, a number that represents the number of seconds our data will live in the store - and lastly, the stored data as JSON.

//index.js
const express = require("express");
const redisClient = require("./cache.js");

const app = express();

app.get("/heavy-task",(req, res) => {
  const { searchTerm } = req.query;

  const result = heavyTask(searchTerm);

  const resultJSON =  JSON.stringify(result);

  redisClient.setex(searchTerm, 3600, resultJSON);

  res.status(200).json({ result });
});

app.listen(PORT, () => {
  console.log("Server is listening on port " + PORT);
});
Enter fullscreen mode Exit fullscreen mode

Great! now our data will be stored in Redis for the next hour.
Now we will create our checkCache middleware which will run each time the request is received and will simply ask Redis if the searchTerm (key) exists - if so return the data - else next().

//middleware/checkCache.js
const redisClient = require("../cache.js");

const checkCache = (req, res, next) => {
  const { searchTerm } = req.query;
  redisClient.get(searchTerm, (err, result) => {
    if (err) {
      console.error(err);
    }
    if (result) {
      const cachedRes = JSON.parse(result);
      return res.status(200).json({cachedRes});
    } else {
      next();
    }
  });
};

module.exports = checkCache;
Enter fullscreen mode Exit fullscreen mode

Implement our middleware in the handler.

//index.js
const express = require("express");
const redisClient = require("./cache.js");
const checkCache = require("./middleware/checkCache.js");

const app = express();

app.get("/heavy-task",checkCache,(req, res) => {
  const { searchTerm } = req.query;

  const result = heavyTask(searchTerm);

  const resultJSON =  JSON.stringify(result);

  redisClient.setex(searchTerm, 3600, resultJSON);

  res.status(200).json({ result });
});

app.listen(PORT, () => {
  console.log("Server is listening on port " + PORT);
});
Enter fullscreen mode Exit fullscreen mode

That's It! now our requests are easily cached with Redis.
Hope you found this simple guide helpful 😄

Oldest comments (0)