Skip to content

Migrating from node_redis

Zihua Li edited this page Feb 25, 2021 · 10 revisions

It should be straightforward to migrate from node_redis to ioredis as most APIs are compatible, with some exceptions:

  • constructor. node_redis use var client = redis.createClient() to create a new RedisClient instance, whereas ioredis prefer to var redis = new Redis(). For reasons of compatibility, ioredis supports var redis = Redis.createClient() as well, but this syntax is deprecated.

  • The options passed to the constructor are different. See API#new_Redis.

  • ioredis considers null/undefined as empty strings, while node_redis will convert them to "null"/"undefined". For instance:

    // node_redis
    client.set('foo', null);
    client.get('foo', function(_, res) {
      console.log(typeof res, res); // "string", "null"
    });
    
    // ioredis
    redis.set('foo', null);
    redis.get('foo', function(_, res) {
      console.log(typeof res, res); // "string", ""
    });
  • Transaction. The result of transaction in node_redis and ioredis are different, for instance:

    // node_redis
    client.multi().set('foo').get('foo').exec(function (err, res) {
      /* err is: 
          [
            [Error: Error: ERR wrong number of arguments for 'set' command],
            [Error: Error: EXECABORT Transaction discarded because of previous errors.]
          ]
         res is undefined
      */
    });
    
    // ioredis
    redis.multi().set('foo').get('foo').exec(function (err, res) {
      /* err is:
         { [ReplyError: EXECABORT Transaction discarded because of previous errors.]
           name: 'ReplyError',
           message: 'EXECABORT Transaction discarded because of previous errors.',
           command: { name: 'exec', args: [] },
           previousErrors:
           [ { [ReplyError: ERR wrong number of arguments for 'set' command]
             name: 'ReplyError',
             message: 'ERR wrong number of arguments for \'set\' command',
             command: [Object] } ] }
         res is undefined
      */
    });
    
    // node_redis
    client.multi().set('foo', 'bar').lpush('foo', 1).exec(function (err, res) {
      /* err is: null
         res is [ 'OK', 'WRONGTYPE Operation against a key holding the wrong kind of value' ]
      */
    });
    
    // ioredis
    redis.multi().set('foo', 'bar').lpush('foo', 1).exec(function (err, res) {
      /* err is: null
         res is [
           [ null, 'OK' ],
           [ { [ReplyError: WRONGTYPE Operation against a key holding the wrong kind of value] } ]
         ]
      */
    });
  • Pub/Sub. When you subscribe multiple channels in node_redis, only the first response is included in the callback. For instance:

    client.subscribe('foo', 'bar', function (err, channel) {
      // channel is 'foo'
      // `bar` isn't subscribed now
    });

    However, in ioredis, callback function will be invoked only when all the channels are subscribed, and the result is the channel count that the client is subscribed:

    redis.subscribe('foo', 'bar', function (err, count) {
      // count is 2
      // both `foo` and `bar` are subscribed now
    });
  • ioredis flattens the parameters of the commands, so the following are the same:

    redis.sadd('set', [1, 3, 5, 7]);
    redis.sadd('set', 1, 3, 5, 7);

    And so do the following two:

    redis.get('key', []);
    redis.get('key');
  • ioredis returns an empty object ({}) when hgetall a non-existed key while node_redis returns null.