skip to Main Content

This is a little hard articulate so I hope my title isn’t too terrible.

I have a frontend/backend React/Node.js(REST API) Web app that I want to add Redis support to for storing retrieving app global settings and per-user specific settings (like language preference, last login, etc… simple stuff) So I was considering adding a /settings branch to my backend REST API to push/pull this information from a redis instance.

This is where my Node.js inexperience comes through. I’m looking at using the ioredis client and it seems too easy. If I have a couple of helpers (more than one .js which will call upon redis) will constructing the client as a const in each be safe to do? Or is there another recommended approach to reusing a single instance of it be the way to go?

Here’s a sample of what I’m thinking of doing. Imagine if I had 3 helper modules that require access to the redis client. Should I declare them as const in each? Or centralize them in a single helper module, and get the client from it? Is there a dis-advantage to doing either?

const config = require('config.json');
const redis_url = config.redis_url;

//redis setup
const Redis = require('ioredis');
const redis = new Redis(redis_url);

module.exports = {
   test
}

async function test(id) {
   redis.get(id, function (err, result) {
   if (err) {
      console.error(err);
      throw(err);
   } else {
      return result;
   }
});

Thank you.

2

Answers


  1. Chosen as BEST ANSWER

    Normally what I would do (in Java say) is implement any explicit class with singleton access the hold the connection and any connection error/reconnect handling.

    All modules in Node.js are already singletons I believe, but what I will probably go with will be a client class to hold it and my own access related methods. Something like:

    const config = require('config.json');
    const Redis = require("ioredis");
    
    class Redis {
    
        constructor(){
            client = new Redis(config.redis_url);
        }
    
        get(key) {
            return this.client.get(key);
        }
    
        set(key, value, ttl) {
            let rp;
            if (ttl === 0) {
                rp = this.client.set(key, value);
            }
            else {
                rp = this.client.set(key, value)
                .then(function(res) {
                    this.client.expire(key, ttl);
                });
            }
            return rp;
        }
    
    }
    
    module.exports = new Redis;
    

    I'll probably include a data_init() method to check and preload an initial key/value structure on first connect.


  2. If no redis conflicts…

    If the different "helper" modules you are referring to have no conflicts when interacting with redis, such as overwriting / using the same redis keys, then I can’t see any reason not to use the same redis instance (as outlined by garlicman) and export this to the different modules in which it is used.

    Otherwise use separate redis databases…

    If you do require separate redis database connections, redis ships with 16 databases so you can specify which to connect to when creating a new instance – see below:

    const redis = new Redis({ // SET UP CONFIG FOR CONNECTION TO REDIS
        port: 6379, // Redis port
        host: 127.0.0.1, // Redis host
        family: 4, // 4 (IPv4) or 6 (IPv6)
        db: 10, // Redis database to connect to
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search