Redis Protocol Parser for Node.js

3.0.0 · active · verified Sun Apr 19

redis-parser is a high-performance JavaScript implementation of the Redis Serialization Protocol (RESP) parser, specifically designed for Node.js environments. It serves as the underlying parsing engine for popular Redis clients like node-redis and ioredis. The current stable version is 3.0.0. This library focuses on efficiently converting raw Redis protocol buffers into usable JavaScript data structures, supporting various RESP data types including strings, numbers, arrays, and errors. Its development prioritizes performance, especially for large data structures, and graceful handling of malformed input, making it a critical component for robust Redis client libraries. It also exports dedicated error classes for specific parsing and reply errors.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart initializes `redis-parser` with necessary callback functions for handling parsed replies, standard errors, and critical protocol errors. It demonstrates feeding various Redis protocol buffers to the parser's `execute` method and dynamically adjusting parsing options like `stringNumbers` for safe handling of large integers.

const Parser = require('redis-parser');

class MyRedisClient {
  constructor() {
    this.replies = [];
    this.errors = [];
    this.fatalErrors = [];
    this.parser = new Parser({
      returnReply: this.handleReply.bind(this),
      returnError: this.handleError.bind(this),
      returnFatalError: this.handleFatalError.bind(this),
      returnBuffers: false, // Default: return strings instead of Buffers
      stringNumbers: false  // Default: return JavaScript numbers, not strings
    });
  }

  handleReply(reply) {
    this.replies.push(reply);
    console.log('Received Reply:', reply);
  }

  handleError(err) {
    this.errors.push(err);
    console.error('Received Error:', err.message);
  }

  handleFatalError(err) {
    this.fatalErrors.push(err);
    console.error('Received FATAL Error (protocol error):', err.message);
    // In a real Redis client, this is where you would typically:
    // 1. Log the error for debugging.
    // 2. Reject all outstanding commands.
    // 3. Destroy the current socket connection.
    // 4. Attempt to reconnect to the Redis server.
    // This prevents further data corruption due to protocol desynchronization.
  }

  processStreamData(dataBuffer) {
    // Simulate receiving raw Redis protocol data (as a Buffer) from a stream
    this.parser.execute(dataBuffer);
  }
}

const client = new MyRedisClient();

// Simulate receiving various Redis protocol responses
client.processStreamData(Buffer.from('$5\r\nHello\r\n')); // Bulk String "Hello"
client.processStreamData(Buffer.from(':12345\r\n'));    // Integer 12345
client.processStreamData(Buffer.from('*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n')); // Array ["foo", "bar"]
client.processStreamData(Buffer.from('-ERR unknown command `FOO`\r\n')); // Error Reply

console.log('\n--- Parser State & Collected Data ---');
console.log('Total Replies:', client.replies.length, client.replies);
console.log('Total Errors:', client.errors.length, client.errors.map(e => e.message));

// Demonstrate dynamic option change: return numbers as strings for large integers
client.parser.setStringNumbers(true);
client.processStreamData(Buffer.from(':90071992547409920\r\n')); // A number larger than Number.MAX_SAFE_INTEGER
console.log('Last Reply (string number):', client.replies[client.replies.length - 1]);

view raw JSON →