Skip to content

Commit 06c3d82

Browse files
committed
Update README.MD
1 parent 4d659f0 commit 06c3d82

File tree

1 file changed

+337
-3
lines changed

1 file changed

+337
-3
lines changed

README.md

+337-3
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@ To install node-redis, simply:
3939
npm install redis
4040
```
4141

42-
> "redis" is the "whole in one" package that includes all the other packages. If you only need a subset of the commands, you can install the individual packages. See the list below.
42+
> "redis" is the "whole in one" package that includes all the other packages. If you only need a subset of the commands,
43+
> you can install the individual packages. See the list below.
4344
4445
## Packages
4546

4647
| Name | Description |
47-
|------------------------------------------------|---------------------------------------------------------------------------------------------|
48+
| ---------------------------------------------- | ------------------------------------------------------------------------------------------- |
4849
| [`redis`](./packages/redis) | The client with all the ["redis-stack"](https://github.com/redis-stack/redis-stack) modules |
4950
| [`@redis/client`](./packages/client) | The base clients (i.e `RedisClient`, `RedisCluster`, etc.) |
5051
| [`@redis/bloom`](./packages/bloom) | [Redis Bloom](https://redis.io/docs/data-types/probabilistic/) commands |
@@ -53,7 +54,340 @@ npm install redis
5354
| [`@redis/time-series`](./packages/time-series) | [Redis Time-Series](https://redis.io/docs/data-types/timeseries/) commands |
5455
| [`@redis/entraid`](./packages/entraid) | Secure token-based authentication for Redis clients using Microsoft Entra ID |
5556

56-
> Looking for a high-level library to handle object mapping? See [redis-om-node](https://github.com/redis/redis-om-node)!
57+
> Looking for a high-level library to handle object mapping?
58+
> See [redis-om-node](https://github.com/redis/redis-om-node)!
59+
60+
## Installation
61+
62+
Start a redis via docker:
63+
64+
```bash
65+
docker run -p 6379:6379 -d redis:8.0-rc1
66+
```
67+
68+
To install node-redis, simply:
69+
70+
```bash
71+
npm install redis
72+
```
73+
74+
## Usage
75+
76+
### Basic Example
77+
78+
```typescript
79+
import { createClient } from "redis";
80+
81+
const client = await createClient()
82+
.on("error", (err) => console.log("Redis Client Error", err))
83+
.connect();
84+
85+
await client.set("key", "value");
86+
const value = await client.get("key");
87+
client.destroy();
88+
```
89+
90+
The above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in
91+
the format `redis[s]://[[username][:password]@][host][:port][/db-number]`:
92+
93+
```typescript
94+
createClient({
95+
url: "redis://alice:foobared@awesome.redis.server:6380",
96+
});
97+
```
98+
99+
You can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in
100+
the [client configuration guide](./docs/client-configuration.md).
101+
102+
To check if the the client is connected and ready to send commands, use `client.isReady` which returns a boolean.
103+
`client.isOpen` is also available. This returns `true` when the client's underlying socket is open, and `false` when it
104+
isn't (for example when the client is still connecting or reconnecting after a network error).
105+
106+
### Redis Commands
107+
108+
There is built-in support for all of the [out-of-the-box Redis commands](https://redis.io/commands). They are exposed
109+
using the raw Redis command names (`HSET`, `HGETALL`, etc.) and a friendlier camel-cased version (`hSet`, `hGetAll`,
110+
etc.):
111+
112+
```typescript
113+
// raw Redis commands
114+
await client.HSET("key", "field", "value");
115+
await client.HGETALL("key");
116+
117+
// friendly JavaScript commands
118+
await client.hSet("key", "field", "value");
119+
await client.hGetAll("key");
120+
```
121+
122+
Modifiers to commands are specified using a JavaScript object:
123+
124+
```typescript
125+
await client.set("key", "value", {
126+
EX: 10,
127+
NX: true,
128+
});
129+
```
130+
131+
Replies will be transformed into useful data structures:
132+
133+
```typescript
134+
await client.hGetAll("key"); // { field1: 'value1', field2: 'value2' }
135+
await client.hVals("key"); // ['value1', 'value2']
136+
```
137+
138+
`Buffer`s are supported as well:
139+
140+
```typescript
141+
await client.hSet("key", "field", Buffer.from("value")); // 'OK'
142+
await client.hGetAll(commandOptions({ returnBuffers: true }), "key"); // { field: <Buffer 76 61 6c 75 65> }
143+
```
144+
145+
### Unsupported Redis Commands
146+
147+
If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:
148+
149+
```typescript
150+
await client.sendCommand(["SET", "key", "value", "NX"]); // 'OK'
151+
152+
await client.sendCommand(["HGETALL", "key"]); // ['key1', 'field1', 'key2', 'field2']
153+
```
154+
155+
### Transactions (Multi/Exec)
156+
157+
Start a [transaction](https://redis.io/topics/transactions) by calling `.multi()`, then chaining your commands. When
158+
you're done, call `.exec()` and you'll get an array back with your results:
159+
160+
```typescript
161+
await client.set("another-key", "another-value");
162+
163+
const [setKeyReply, otherKeyValue] = await client
164+
.multi()
165+
.set("key", "value")
166+
.get("another-key")
167+
.exec(); // ['OK', 'another-value']
168+
```
169+
170+
You can also [watch](https://redis.io/topics/transactions#optimistic-locking-using-check-and-set) keys by calling
171+
`.watch()`. Your transaction will abort if any of the watched keys change.
172+
173+
174+
### Blocking Commands
175+
176+
In v4, `RedisClient` had the ability to create a pool of connections using an "Isolation Pool" on top of the "main"
177+
connection. However, there was no way to use the pool without a "main" connection:
178+
179+
```javascript
180+
const client = await createClient()
181+
.on("error", (err) => console.error(err))
182+
.connect();
183+
184+
await client.ping(client.commandOptions({ isolated: true }));
185+
```
186+
187+
In v5 we've extracted this pool logic into its own class—`RedisClientPool`:
188+
189+
```javascript
190+
const pool = await createClientPool()
191+
.on("error", (err) => console.error(err))
192+
.connect();
193+
194+
await pool.ping();
195+
```
196+
197+
To learn more about isolated execution, check out the [guide](./docs/isolated-execution.md).
198+
199+
### Pub/Sub
200+
201+
See the [Pub/Sub overview](./docs/pub-sub.md).
202+
203+
### Scan Iterator
204+
205+
[`SCAN`](https://redis.io/commands/scan) results can be looped over
206+
using [async iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator):
207+
208+
```typescript
209+
for await (const key of client.scanIterator()) {
210+
// use the key!
211+
await client.get(key);
212+
}
213+
```
214+
215+
This works with `HSCAN`, `SSCAN`, and `ZSCAN` too:
216+
217+
```typescript
218+
for await (const { field, value } of client.hScanIterator("hash")) {
219+
}
220+
for await (const member of client.sScanIterator("set")) {
221+
}
222+
for await (const { score, value } of client.zScanIterator("sorted-set")) {
223+
}
224+
```
225+
226+
You can override the default options by providing a configuration object:
227+
228+
```typescript
229+
client.scanIterator({
230+
TYPE: "string", // `SCAN` only
231+
MATCH: "patter*",
232+
COUNT: 100,
233+
});
234+
```
235+
236+
### [Programmability](https://redis.io/docs/manual/programmability/)
237+
238+
Redis provides a programming interface allowing code execution on the redis server.
239+
240+
#### [Functions](https://redis.io/docs/manual/programmability/functions-intro/)
241+
242+
The following example retrieves a key in redis, returning the value of the key, incremented by an integer. For example,
243+
if your key _foo_ has the value _17_ and we run `add('foo', 25)`, it returns the answer to Life, the Universe and
244+
Everything.
245+
246+
```lua
247+
#!lua name=library
248+
249+
redis.register_function {
250+
function_name = 'add',
251+
callback = function(keys, args) return redis.call('GET', keys[1]) + args[1] end,
252+
flags = { 'no-writes' }
253+
}
254+
```
255+
256+
Here is the same example, but in a format that can be pasted into the `redis-cli`.
257+
258+
```
259+
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\"}}"
260+
```
261+
262+
Load the prior redis function on the _redis server_ before running the example below.
263+
264+
```typescript
265+
import { createClient } from "redis";
266+
267+
const client = createClient({
268+
functions: {
269+
library: {
270+
add: {
271+
NUMBER_OF_KEYS: 1,
272+
transformArguments(key: string, toAdd: number): Array<string> {
273+
return [key, toAdd.toString()];
274+
},
275+
transformReply(reply: number): number {
276+
return reply;
277+
},
278+
},
279+
},
280+
},
281+
});
282+
283+
await client.connect();
284+
285+
await client.set("key", "1");
286+
await client.library.add("key", 2); // 3
287+
```
288+
289+
#### [Lua Scripts](https://redis.io/docs/manual/programmability/eval-intro/)
290+
291+
The following is an end-to-end example of the prior concept.
292+
293+
```typescript
294+
import { createClient, defineScript } from "redis";
295+
296+
const client = createClient({
297+
scripts: {
298+
add: defineScript({
299+
NUMBER_OF_KEYS: 1,
300+
SCRIPT: 'return redis.call("GET", KEYS[1]) + ARGV[1];',
301+
transformArguments(key: string, toAdd: number): Array<string> {
302+
return [key, toAdd.toString()];
303+
},
304+
transformReply(reply: number): number {
305+
return reply;
306+
},
307+
}),
308+
},
309+
});
310+
311+
await client.connect();
312+
313+
await client.set("key", "1");
314+
await client.add("key", 2); // 3
315+
```
316+
317+
### Disconnecting
318+
319+
The `QUIT` command has been deprecated in Redis 7.2 and should now also be considered deprecated in Node-Redis. Instead
320+
of sending a `QUIT` command to the server, the client can simply close the network connection.
321+
322+
`client.QUIT/quit()` is replaced by `client.close()`. and, to avoid confusion, `client.disconnect()` has been renamed to
323+
`client.destroy()`.
324+
325+
```typescript
326+
client.destroy();
327+
```
328+
329+
### Auto-Pipelining
330+
331+
Node Redis will automatically pipeline requests that are made during the same "tick".
332+
333+
```typescript
334+
client.set("Tm9kZSBSZWRpcw==", "users:1");
335+
client.sAdd("users:1:tokens", "Tm9kZSBSZWRpcw==");
336+
```
337+
338+
Of course, if you don't do something with your Promises you're certain to
339+
get [unhandled Promise exceptions](https://nodejs.org/api/process.html#process_event_unhandledrejection). To take
340+
advantage of auto-pipelining and handle your Promises, use `Promise.all()`.
341+
342+
```typescript
343+
await Promise.all([
344+
client.set("Tm9kZSBSZWRpcw==", "users:1"),
345+
client.sAdd("users:1:tokens", "Tm9kZSBSZWRpcw=="),
346+
]);
347+
```
348+
349+
### Clustering
350+
351+
Check out the [Clustering Guide](./docs/clustering.md) when using Node Redis to connect to a Redis Cluster.
352+
353+
### Events
354+
355+
The Node Redis client class is an Nodejs EventEmitter and it emits an event each time the network status changes:
356+
357+
| Name | When | Listener arguments |
358+
| ----------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- |
359+
| `connect` | Initiating a connection to the server | _No arguments_ |
360+
| `ready` | Client is ready to use | _No arguments_ |
361+
| `end` | Connection has been closed (via `.disconnect()`) | _No arguments_ |
362+
| `error` | An error has occurred—usually a network issue such as "Socket closed unexpectedly" | `(error: Error)` |
363+
| `reconnecting` | Client is trying to reconnect to the server | _No arguments_ |
364+
| `sharded-channel-moved` | See [here](./docs/pub-sub.md#sharded-channel-moved-event) | See [here](./docs/pub-sub.md#sharded-channel-moved-event) |
365+
366+
> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and
367+
> an `error` occurs, that error will be thrown and the Node.js process will exit. See the [ > `EventEmitter` docs](https://nodejs.org/api/events.html#events_error_events) for more details.
368+
369+
> The client will not emit [any other events](./docs/v3-to-v4.md#all-the-removed-events) beyond those listed above.
370+
371+
## Supported Redis versions
372+
373+
Node Redis is supported with the following versions of Redis:
374+
375+
| Version | Supported |
376+
| ------- | ------------------ |
377+
| 8.0.z | :heavy_check_mark: |
378+
| 7.0.z | :heavy_check_mark: |
379+
| 6.2.z | :heavy_check_mark: |
380+
| 6.0.z | :heavy_check_mark: |
381+
| 5.0.z | :heavy_check_mark: |
382+
| < 5.0 | :x: |
383+
384+
> Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support.
385+
386+
## Migration
387+
388+
- [From V3 to V4](docs/v3-to-v4.md)
389+
- [From V4 to V5](docs/v4-to-v5.md)
390+
- [V5](docs/v5.md)
57391

58392
## Contributing
59393

0 commit comments

Comments
 (0)