Introduction to Redis and Caching with Node.js
Tags: redis, node, javascript, serverless
Published: 2021-03-22 15:00:52

---
title: Introduction to Redis and Caching with Node.js
published: true
description: Redis is an in-memory data structure used for cache.
tags: redis, nodejs, javascript, serverless 
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hu4vce4wwazki479gj7j.jpg
---

## What is Redis?

Redis is an open-source, in-memory data structure store, used as a NoSQL database for the cache to improve the overall response rate for most frequently requested data.

In this blog, we will develop Notes Taking App API, We will implement two feature,

1. Take a note from the user.
2. Return a note back to the user.

But here will use Redis, to cache note. If the user requests the same note frequently, we will return notes stored in Redis.

##### REST API Routes
```
POST => /api/notes => Create notes
GET  => /api/notes/:id => Get a note
```


#### Software Requirements

Let's begin,
Install the required packages on your local machine:

`npm install express body-parser mongoose redis --save`

#### Set up Redis database with Upstash,

Upstash is a serverless database for Redis, with servers/instances, you pay-per-hour or a fixed price. With Serverless, you pay per-request.

This means you're not charged when the database isn't in use. Upstash configures and manages the database for you.

Let's start with creating an account on Upstash,

https://upstash.com/

Now set up database instance,

![Create New Database
](https://miro.medium.com/max/2400/1*WQ4am-ITQFY7X1jFUAUYcg.png "Create New Database
")

![Connect to your database
](https://miro.medium.com/max/2400/1*NS2-cVYWz2z_qZR0m8ra5Q.png "Connect to your database
")

Create a simple server and connect to the MongoDB database:

```javascript
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const redis = require('redis');

const app = express();
app.use(bodyParser.json());

mongoose.connect('mongodb://localhost:27017/', {
    dbName: 'notes',
    useNewUrlParser: true,
    useUnifiedTopology: true
}, err => err ? console.log(err) : console.log('Connected to database'));


app.listen(3000, () => console.log('Server running at port 3000'));
```

Now connect to the Redis server using the configuration provided by Upstash:

```javascript
//Redis connection
const redis = require("redis");
var client = redis.createClient({
  host: "eu1-capital-cattle-31290.upstash.io",
  port: "31290",
  password: "YOUR_REDIS_PASSWORD",
});
client.on("error", function (err) {
  throw err;
});
```

Mongoose Model:

```javascript
//Mongoose Model
const NoteSchema = new mongoose.Schema({
  title: String,
  note: String,
});
const note = mongoose.model("Note", NoteSchema);
```

Now implement routes for API

Get a note from the user and store it Redis and MongoDB:

```javascript
//Create notes
app.post("/api/notes", (req, res, next) => {
  const { title, note } = req.body;
  const _note = new Note({
    title: title,
    note: note,
  });
  _note.save((err, note) => {
    if (err) {
      return res.status(404).json(err);
    }
    //Store in Redis
    client.setex(note.id, 60, JSON.stringify(note), (err, reply) => {
      if (err) {
        console.log(err);
      }
      console.log(reply);
    });
    return res.status(201).json({
      message: "Note has been saved",
      note: note,
    });
  });
});
```

Take look here in the code, we used a method `setex` to store data in Redis.

This method takes 4 parameters

1. `id` : Unique ID must be provided to store data. It must be a string.

2. `seconds` : Expiry time in seconds as a number.

3. `value` : Actual data to store in Redis. It must be a string. So we are serializing `object` into `string` .

4. `callback` : Callback takes two parameters `err` and `reply`.


Create a note
![Create a note
](https://miro.medium.com/max/2400/1*o07mPlNL0ML-0ZWawZ8L8g.png "Create a note
")


Now retrieve data, first, we have to check in Redis for data, if data is not available in Redis then we have to make a query in the database.

For that, we have to write middleware that checks the requested data in Redis.

Middleware:

```javascript
const isCached = (req, res, next) => {
  const { id } = req.params;
  //First check in Redis
  client.get(id, (err, data) => {
    if (err) {
      console.log(err);
    }
    if (data) {
      const reponse = JSON.parse(data);
      return res.status(200).json(reponse);
    }
    next();
  });
};
```

In the above middleware, we used `get()` method to retrieve existing data from Redis. `get(id, callback())`.

Here we parsed `string` back to the `object`.

Now use this middleware on `get` request:

```javascript
app.get("/api/notes/:id", isCached, (req, res, next) => {
  const { id } = req.params;
  Note.findById(id, (err, note) => {
    if (err) {
      return res.status(404).json(err);
    }
    return res.status(200).json({
      note: note,
    });
  });
});
```


First time retrieves data. It took 11ms
![First time retrieves data. It took 11ms
](https://miro.medium.com/max/2400/1*R2gGYqvKL4HA60h97c5XaQ.png "First time retrieves data. It took 11ms
")


Next, we retried to get data, It took 5ms
![Next, we retried to get data, It took 5ms.
](https://miro.medium.com/max/2400/1*ap-PRF_pKPfnEewxKYtaaA.png "Next, we retried to get data, It took 5ms.
")


## Code

```javascript
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const redis = require('redis');

const app = express();

app.use(bodyParser.json());

//Redis connection
var client = redis.createClient({
  host: "eu1-capital-cattle-31290.upstash.io",
  port: "31290",
  password: "YOUR_REDIS_PASSWORD",
});
client.on("error", function (err) {
  throw err;
});

//MongoDB connection
mongoose.connect('mongodb://localhost:27017/', {
    dbName: 'notes',
    useNewUrlParser: true,
    useUnifiedTopology: true
}, err => err ? console.log(err) : console.log('Connected to database'));

//Mongoose Model
const NoteSchema = new mongoose.Schema({
    title: String,
    note: String
});

const Note = mongoose.model('Note', NoteSchema);

//Create notes
app.post('/api/notes', (req, res, next) => {

    const { title, note } = req.body;

    const _note = new Note({
        title: title,
        note: note
    });

    _note.save((err, note) => {
        if (err) {
            return res.status(404).json(err);
        }

        //Store in Redis
        client.setex(note.id, 60, JSON.stringify(note), (err, reply) => {
            if (err) {
                console.log(err);
            }
            console.log(reply);
        });

        return res.status(201).json({
            message: 'Note has been saved',
            note: note
        });
    })

});

const isCached = (req, res, next) => {

    const { id } = req.params;

    //First check in Redis
    client.get(id, (err, data) => {
        if (err) {
            console.log(err);
        }
        if (data) {
            const reponse = JSON.parse(data);
            return res.status(200).json(reponse);
        }
        next();
    });
}

app.get('/api/notes/:id', isCached, (req, res, next) => {

    const { id } = req.params;

    Note.findById(id, (err, note) => {
        if (err) {
            return res.status(404).json(err);
        }
        return res.status(200).json({
            note: note
        });
    });
});

app.listen(3000, () => console.log('Server running at port 3000'));
```

Check out Upstash for production: https://upstash.com/