Redis cache with docker

docker-redis.jpg

let’s begin with what is caching ?

Caching is the process of storing copies of files in a cache, or temporary storage location, so that they can be accessed more quickly. “ Technically, we cache data that is frequently requested by the user to reduce the number of requests served by the server”.

why using Redis ?

Redis comes in handy when performing caching because it is an in-memory database and can query the database in a few milliseconds, sometimes sub-millisecond. Redis is not a plain key-value store, it is actually a data structures server, supporting different kinds of values. While in traditional key-value stores you associate string keys to string values, in Redis the value is not limited to a simple string, but can also hold more complex data structures.

Installing Required Software

1. Node: [https://nodejs.org/en/download/]
2. docker: [https://docs.docker.com/engine/install/ubuntu/]
3. Postman: [https://www.postman.com/downloads/]

Installation

Create a folder with any name you want and initialize the folder with init command.

npm init -y

Install mongoose, redis and express using npm install command.

npm install redis express axios

Install nodemon as dev dependency

npm install -g nodemon

Run Redis with docker:

we will run Redis with docker, we should pull from docker-hub and then run it locally on a specific port, you choose any port number you want.

the option -d : means that the container still running in the background during your system is up.

open terminal and run the following command

docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest

How to connect to Redis-cli :

its simple open terminal and type : Redis-cli -p “port number” in our case 6379

redis-cli -p 3079

or

sudo docker exec -it CONTAINER_ID redis-cli

you can get the CONTAINER_ID by the following commande :

sudo docker ps

Creating Server node

create server.js file in the root of the folder. it contains our configurations of the web server that we will made, port number where it will be available and Redis implementation.

add the following code in server.js file :

const express = require("express");
const app = express();

const PORT = process.env.PORT || 3020;

app.listen(PORT, () => {
  console.log(`Server started at port: ${PORT}`);
});

Connection to Redis database:

as we mention we run Redis as a docker container exposed on the 6379 port, you can check

//redis connections
const redis = require("redis");
const redisClient = redis.createClient({ url: "redis://localhost:6379" });
redisClient
  .connect()
  .then(() => console.log(`redis connected`))
  .catch((err) => console.log(`redis error: ${err}`));

Creating routes of the API :

we create routes and its logic of retrieving data from an endpoint using asynchronous callback. And this is the very interesting section because we will start building a caching mechanism using redis.

our endpoint will be : jsonplaceholder.typicode.com/users

const endpoint = "https://jsonplaceholder.typicode.com/users/";
/*
fetch data by email check for cache hit
if cache hit
  get data from redis
else
  fetch data by email from endpoint 
  set fetched data in redis 
  and send the data to client
*/ 

app.get("/cache/user/:email", async (req, res) => {
  const email = req.params.email;
  try {
    const emai = await redisClient.get("email").then(async (response) => {
      if (response) {
        res.status(200).send({ email: response });
      } else {
        const response = await axios.get(`${endpoint}?email=${email}`);
        const user = response.data[0].email;
        redisClient.set("email", user);
        res.status(200).send(user);
      }
    });
  } catch (err) {
    res.status(500).send({ error: err.message });
  }
});

Here, GET method is used to fetch single record. In /:email route, the value of email is obtained from req.params object.

this email value is used to fetch data in Redis first, if the record email is not found on Redis cache, it will fetch it from the endpoint using axios get query and return it to the user and save it in the cache in this case.

fetch user by email :

the idea here we with get an user with email and check if there is a key in redis database with this email if yes we will get from cache else we will handle a query with axios from the endpoint to get that user and we will compare the time of response between the two methods to show Redis magic and rapidity.

withouredis.jpg

withredis.jpg

Complete code on my github : https://github.com/aminkammoun/redis-express-nodejs

Conclusion :

our purpose by this example is to show the effect of redis implementation in our web service and its response is so fast comparing with the query response from the server directly

so the utilization of redis is highly recommended in our API to get a robust web service with low latency and with its simplicity in use.

And We Are Done!!!

Feel free to test it in Postman.