Basic server side caching using Redis in nodejs
Tags: webdev, node, redis, caching
Published: 2021-11-23 11:20:21

Caching is the process of storing copies of files in a cache, or temporary storage location, so that they can be accessed more quickly. 
Caching helps us in making our website more faster, respond to user queries faster by acting as a middleware between server and database.


<img src="https://codeahoy.com/img/cache-aside.png" alt="Caching process" style="height: 100px; width:100px;"/>

***There is commonly two types of caching :-***
 
1) Server side caches are generally used to avoid making expensive database operations repeatedly to serve up the same content to lots of different clients. 

2) Client side caches are used to avoid transferring the same data over the network repeatedly.

Today we will learn basic server side caching using redis(a fast, open source, in-memory, key-value data store).


***Installing Redis:-***

Firstly we will need to install redis before using it in our project.

Installing redis on Mac using Homebrew -
```
brew install redis
brew services start redis
redis-server /usr/local/etc/redis.conf

```

***Installing redis on Windows -***
```
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install redis-server
sudo service redis-server restart
```

***Installing redis on ubuntu -***
```
sudo apt update
sudo apt install redis-server
sudo nano /etc/redis/redis.conf
```
Inside the file, find the supervised directive. This directive allows you to declare an init system to manage Redis as a service, providing you with more control over its operation. The supervised directive is set to no by default. Since you are running Ubuntu, which uses the systemd init system, change this to systemd:
```
. . .

# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
#   supervised no      - no supervision interaction
#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode
#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
#   supervised auto    - detect upstart or systemd method based on
#                        UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
#       They do not enable continuous liveness pings back to your supervisor.
supervised systemd

. . .
```
and finally restart redis
```
sudo systemctl restart redis.service
```


***1)*** In the project folder initialise the project using npm init and install express, redis and node-fetch(same as fetch in javascript for making requests to rest clients ). Also install nodemon as dev dependency.
```
npm init -y
npm install --save express redis
npm install --dev nodemon 
```


***2)*** In the project folder paste this code in app.js importing express , nodefetch and redis and start basic server.
```
const express = require("express");
const app = express();
const redis = require("redis");
const fetch = require("node-fetch");

app.get("/", (req, res) => {
    res.status(200).send("This is homepage!");
})

app.listen(8080, () => {
     console.log("Server started!");
});
```


***3)*** Create a redis client passing default redis port(6379) as parameter and also create a new route(/post) that will fetch data from https://api.github.com/users and send data as response.
We will cache this data on our first visit to server and after that in all visits we will check if data is stored in cache or not . If it is stored we will not fetch it instead send response from cache.
```
const express = require("express");
const app = express();
const redis = require("redis");
const fetch = require("node-fetch");

const client = redis.createClient(6379);

app.get("/posts", (req, res) => {
    console.log("fetching data")    // this will tell uswe are fetching data  from api
    fetch(`https://api.github.com/users`,((response)=>{
       const data = response.json();
       client.set("userData",data);   // save data(key,value pair) in redis in form of cache

     res.send({data:data});
   })
})

app.listen(8080, () => {
     console.log("Server started!");
});
```

Here we used client.set(key,value) for saving data in redis.



***4)*** We will now create a middleware and add it in "/post" route for checking if cache already exists.If data is already present in cache we will return it directly else we will leave our middleware and fetch it from the route.

```
const checkDataInCache = (req,res,next) =>{
  const  data = client.get("userData"); //get data from cache and check if it exists
  if(data !== null){
    res.send({data:data});
  }else{
    next();
  }
}
```

Now we are almost done with our code(full code given at last) and now we will test it.

If we send a get request at "/posts" at first we will see log as " fetching .." that  shows that we are fetching data from api.
But after that in all requests there will be no log and data will be loaded more quickly.
(We can check for the speed by going in console and them network).


This was basic representation of how to use caching.Full code given below.
Hope it helps!!
```
const express = require("express");
const app = express();
const redis = require("redis");
const fetch = require("node-fetch");

const client = redis.createClient(6379);

app.get("/posts",checkDataInCache, (req, res) => {
    console.log("fetching data")    // this will tell us if we are fetching data  from api
    fetch(`https://api.github.com/users`,((response)=>{
       const data = response.json();
       client.set("userData",data);   // save data(key,value pair) in redis in form of cache

     res.send({data:data});
   })
})

const checkDataInCache = (req,res,next) =>{
  const  data = client.get("userData"); //get data from cache and check if it exists
  if(data !== null){
    res.send({data:data});
  }else{
    next();
  }
}
app.listen(8080, () => {
     console.log("Server started!");
});
```