Node-Redis
Packages
Name | Description |
---|---|
:--- | :--- |
redis | |
@redis/client | |
@redis/bloom | Redis Bloom commands |
@redis/graph | Redis Graph commands |
@redis/json | Redis JSON commands |
@redis/search | RediSearch commands |
@redis/time-series | Redis Time-Series commands |
⚠️In version 4.1.0 we moved our subpackages from @node-redis to @redis. If you're just using npm install redis, you don't need to do anything—it'll upgrade automatically. If you're using the subpackages directly, you'll need to point to the new scope (e.g. @redis/client instead of @node-redis/client ).
Installation
- ``` shell
- docker run -p 6379:6379 -it redis/redis-stack-server:latest
- ```
- ``` shell
- npm install redis
- ```
⚠️The new interface is clean and cool, but if you have an existing codebase, you'll want to read the migration guide.
Usage
Basic Example
- ``` ts
- import { createClient } from 'redis';
- const client = createClient();
- client.on('error', err => console.log('Redis Client Error', err));
- await client.connect();
- await client.set('key', 'value');
- const value = await client.get('key');
- await client.disconnect();
- ```
- ``` ts
- createClient({
- url: 'redis://alice:foobared@awesome.redis.server:6380'
- });
- ```
Redis Commands
- ``` ts
- // raw Redis commands
- await client.HSET('key', 'field', 'value');
- await client.HGETALL('key');
- // friendly JavaScript commands
- await client.hSet('key', 'field', 'value');
- await client.hGetAll('key');
- ```
- ``` ts
- await client.set('key', 'value', {
- EX: 10,
- NX: true
- });
- ```
- ``` ts
- await client.hGetAll('key'); // { field1: 'value1', field2: 'value2' }
- await client.hVals('key'); // ['value1', 'value2']
- ```
- ``` ts
- await client.hSet('key', 'field', Buffer.from('value')); // 'OK'
- await client.hGetAll(
- commandOptions({ returnBuffers: true }),
- 'key'
- ); // { field:
} - ```
Unsupported Redis Commands
- ``` ts
- await client.sendCommand(['SET', 'key', 'value', 'NX']); // 'OK'
- await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'field2']
- ```
Transactions (Multi/Exec)
- ``` ts
- await client.set('another-key', 'another-value');
- const [setKeyReply, otherKeyValue] = await client
- .multi()
- .set('key', 'value')
- .get('another-key')
- .exec(); // ['OK', 'another-value']
- ```
Blocking Commands
- ``` ts
- import { commandOptions } from 'redis';
- const blPopPromise = client.blPop(
- commandOptions({ isolated: true }),
- 'key',
- 0
- );
- await client.lPush('key', ['1', '2']);
- await blPopPromise; // '2'
- ```
Pub/Sub
Scan Iterator
- ``` ts
- for await (const key of client.scanIterator()) {
- // use the key!
- await client.get(key);
- }
- ```
- ``` ts
- for await (const { field, value } of client.hScanIterator('hash')) {}
- for await (const member of client.sScanIterator('set')) {}
- for await (const { score, value } of client.zScanIterator('sorted-set')) {}
- ```
- ``` ts
- client.scanIterator({
- TYPE: 'string', // `SCAN` only
- MATCH: 'patter*',
- COUNT: 100
- });
- ```
Programmability
Functions
- ``` lua
- #!lua name=library
- redis.register_function {
- function_name = 'add',
- callback = function(keys, args) return redis.call('GET', keys[1]) + args[1] end,
- flags = { 'no-writes' }
- }
- ```
- ``` sh
- FUNCTION LOAD "#!lua name=library\nredis.register_function{function_name=\"add\", callback=function(keys, args) return redis.call('GET', keys[1])+args[1] end, flags={\"no-writes\"}}"
- ```
- ``` ts
- import { createClient } from 'redis';
- const client = createClient({
- functions: {
- library: {
- add: {
- NUMBER_OF_KEYS: 1,
- transformArguments(key: string, toAdd: number): Array<string> {
- return [key, toAdd.toString()];
- },
- transformReply(reply: number): number {
- return reply;
- }
- }
- }
- }
- });
- await client.connect();
- await client.set('key', '1');
- await client.library.add('key', 2); // 3
- ```
Lua Scripts
- ``` ts
- import { createClient, defineScript } from 'redis';
- const client = createClient({
- scripts: {
- add: defineScript({
- NUMBER_OF_KEYS: 1,
- SCRIPT:
- 'return redis.call("GET", KEYS[1]) + ARGV[1];',
- transformArguments(key: string, toAdd: number): Array<string> {
- return [key, toAdd.toString()];
- },
- transformReply(reply: number): number {
- return reply;
- }
- })
- }
- });
- await client.connect();
- await client.set('key', '1');
- await client.add('key', 2); // 3
- ```
Disconnecting
.QUIT()/.quit()
- ``` ts
- const [ping, get, quit] = await Promise.all([
- client.ping(),
- client.get('key'),
- client.quit()
- ]); // ['PONG', null, 'OK']
- try {
- await client.get('key');
- } catch (err) {
- // ClosedClient Error
- }
- ```
.disconnect()
- ``` ts
- await client.disconnect();
- ```
Auto-Pipelining
- ``` ts
- client.set('Tm9kZSBSZWRpcw==', 'users:1');
- client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==');
- ```
- ``` ts
- await Promise.all([
- client.set('Tm9kZSBSZWRpcw==', 'users:1'),
- client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==')
- ]);
- ```
Clustering
Events
Name | When | Listener arguments |
---|---|---|
:--- | :--- | :--- |
connect | Initiating a connection to the server | No arguments |
ready | Client is ready to use | No arguments |
end | Connection has been closed (via .quit() or .disconnect()) | No arguments |
error | An error has occurred—usually a network issue such as "Socket closed unexpectedly" | (error: Error) |
reconnecting | Client is trying to reconnect to the server | No arguments |
sharded-channel-moved | See here | See here |
⚠️You MUSTlisten to error events. If a client doesn't have at least one error listener registered and an error occurs, that error will be thrown and the Node.js process will exit. See the EventEmitter docs for more details.
The client will not emit any other events beyond those listed above.
Supported Redis versions
Version | Supported |
---|---|
:--- | :--- |
7.0.z | ✔️ |
6.2.z | ✔️ |
6.0.z | ✔️ |
5.0.z | ✔️ |
< 5.0 | ❌ |
Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support.