Redis types

The Redis RESP protocol consists of just five types, therefore in your filters, the context.packet object will always be one of these five types:

  • simple strings: basic strings used for small amounts of text

  • bulk string: arbitrarily long strings (up to 512MB)

  • error: used to send errors back to the client

  • integer: used to communicate numbers

  • array: contains any number of any of the five types, including array

However, for requests, the type is always Array. A Redis command such as:

set Foo "My value"

will be received by request filters as an array of BulkStrings:

["set", "FOO", "My value"]


All types have a packetType property:

var pktType = context.packet.packetType;

switch(pktType) {

case 'SimpleString':

break;

case 'Error':

break;

case 'BulkString':

break;

case 'Integer':

break;

case 'Array':

break;

}


All types implement the following methods:

  • getPacketType(): returns a string, one of: "SimpleString:, "BulkString", "Integer", "Array" or "Error"

  • isSimpleString(): returns true if the object is a SimpleString

  • isBulkString(): returns true if the object is a BulkString

  • isInteger(): returns true if the object is an Integer

  • isArray(): returns true if the object is an Array

  • isError(): returns true if the object is an Error object (used only in responses)

  • deepCopy(): returns a deep copy of the entire object (useful for Arrays)

  • canBeMap(): checks whether the object is an Array with an even number of values, and whether all values in even slots (starting at 0) are strings. If this returns true, then the object can be converted to an object by calling toMap(), making it easier to manipulate in code.


SimpleString

A SimpleString object is usually just a string. Its content can be obtained and changed using the string property:

if (context.packet[1].string === 'Foo') {

context.packet[1].string = 'Bar';

}

The value cannot contain <CR> <LF> -- use a BulkString if you need that.

The value of strings can be binary -- either encoded strings (e.g. UTF-8) or actual binary data. By default, UTF-8 encoding is assumed. For strings with other encodings, you can use the getString and setString methods:

var utf16str = context.packet[1].getString("UTF-16");

context.packet[1].setString("New value for string", "UTF-16");

Note that, if the string uses an encoding other than UTF-8, you should not use the string property, since it assumes UTF-8.

The binary value can be accessed using the bytes property:

if (context.packet[1].bytes[0] === 12) {

context.packet[1].bytes[0] = 13;

}

Error

An Error object is sent back by the server whenever it needs to indicate that something went wrong.

The Error type is otherwise exactly like the SimpleString type.

The format, by convention, is normally XXX Message where XXX is the type of the error, e.g. ERR or WRONGTYPE, and Message is a string describing the error. Like SimpleString, Error cannot contain <CR> <LF>.


BulkString

A BulkString object is a string of arbitrary length (up to 512MB), and is most commonly used when returning data.

BulkString objects have an extra property called isNull, indicating a special value indicating the non-existence of a value.

A BulkString is otherwise like a SimpleString, except that its content is unrestricted.


Integer

An Integer object is just an integer number. Its value goes from -2^63-1 to 2^63.

The value can be retrieved and modified using the int property:

if (context.packet[1].int === 12) {

context.packet[1].int = 13;

}


Array

An Array is an ordered list of objects of any of the 5 supported types. It is therefore possible (and common) to have arrays of arrays, and of other types.

Arrays can be used mostly like normal JavaScript arrays:

for (var c of context.packet) {

log.debug("Array contains: " + c);

}

for (var i = 0; i < context.packet.length; i++) {

log.debug("Array contains: " + context.packet[i] + " at index " + i);

}

In addition, arrays implement the following methods from standard JavaScript arrays: push(), pop(), find(), forEach(), shift(), unshift().

Arrays also have a remove(int) method that removes the object at the specified index.

Arrays also implement toHashMap(), which throws an exception if the Array is not in the proper format, otherwise returns a JavaScript object with name/value pairs from the array. Any changes to that object will be reflected in the Array. Existing values will bechanged in place, new key/values will be added to the end of the Array.


Examples

// Does this array contain a specific value?

let found = context.packet.find(c => return c.isBulkString() && c.string === "Foo");


// Add a suffix to every string in the array

if (context.packet.isArray()) {

context.packet.forEach((e, i, a) => {e.isBulkString() && e.string += "suffix"});

}


// Make a deep copy of the request

let copy = context.packet.deepCopy();

copy[0].text = "foo";


// Add a string, an integer and an array to the request

context.packet.push("a string");

context.packet.push(123);

let array = context.redisUtil.createArray();

array.push("Hello");

context.packet.push(array);


// Convert a properly formatted Array to an object and make some changes

if (context.packet.isMap()) {

let cust = context.packet.toMap();

map.street = "Elm Street";

map.creditLine = 30000;

}