Skip to content

Commit 670f0fd

Browse files
committed
Update README.MD
1 parent 4d659f0 commit 670f0fd

File tree

1 file changed

+340
-3
lines changed

1 file changed

+340
-3
lines changed

Diff for: README.md

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

58395
## Contributing
59396

0 commit comments

Comments
 (0)