Implement caching in Node.js with Redis
Tags: javascript, webdev, redis, node
Published: 2022-04-25 21:32:54

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);
});
```

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;
```

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);
});
```

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;
```

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);
});
```

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