@@ -17,24 +17,42 @@ npm i undici
17
17
18
18
## Benchmarks
19
19
20
- The benchmark is a simple ` hello world ` [ example] ( benchmarks/benchmark.js ) using a
20
+ The benchmark is a simple getting data [ example] ( https://github.com/nodejs/undici/blob/main/ benchmarks/benchmark.js) using a
21
21
50 TCP connections with a pipelining depth of 10 running on Node 20.10.0.
22
22
23
- ```
24
- │ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │
25
- |─────────────────────|─────────|─────────────────|───────────|─────────────────────────|
26
- │ got │ 45 │ 1661.71 req/sec │ ± 2.93 % │ - │
27
- │ node-fetch │ 20 │ 2164.81 req/sec │ ± 2.63 % │ + 30.28 % │
28
- │ undici - fetch │ 35 │ 2274.27 req/sec │ ± 2.70 % │ + 36.86 % │
29
- │ http - no keepalive │ 15 │ 2376.04 req/sec │ ± 2.99 % │ + 42.99 % │
30
- │ axios │ 25 │ 2612.93 req/sec │ ± 2.89 % │ + 57.24 % │
31
- │ request │ 40 │ 2712.19 req/sec │ ± 2.92 % │ + 63.22 % │
32
- │ http - keepalive │ 45 │ 4393.25 req/sec │ ± 2.86 % │ + 164.38 % │
33
- │ undici - pipeline │ 45 │ 5484.69 req/sec │ ± 2.87 % │ + 230.06 % │
34
- │ undici - request │ 55 │ 7773.98 req/sec │ ± 2.93 % │ + 367.83 % │
35
- │ undici - stream │ 70 │ 8425.96 req/sec │ ± 2.91 % │ + 407.07 % │
36
- │ undici - dispatch │ 50 │ 9488.99 req/sec │ ± 2.85 % │ + 471.04 % │
37
- ```
23
+ | _ Tests_ | _ Samples_ | _ Result_ | _ Tolerance_ | _ Difference with slowest_ |
24
+ | :-----------------: | :-------: | :--------------: | :---------: | :-----------------------: |
25
+ | undici - fetch | 30 | 3704.43 req/sec | ± 2.95 % | - |
26
+ | http - no keepalive | 20 | 4275.30 req/sec | ± 2.60 % | + 15.41 % |
27
+ | node-fetch | 10 | 4759.42 req/sec | ± 0.87 % | + 28.48 % |
28
+ | request | 40 | 4803.37 req/sec | ± 2.77 % | + 29.67 % |
29
+ | axios | 45 | 4951.97 req/sec | ± 2.88 % | + 33.68 % |
30
+ | got | 10 | 5969.67 req/sec | ± 2.64 % | + 61.15 % |
31
+ | superagent | 10 | 9471.48 req/sec | ± 1.50 % | + 155.68 % |
32
+ | http - keepalive | 25 | 10327.49 req/sec | ± 2.95 % | + 178.79 % |
33
+ | undici - pipeline | 10 | 15053.41 req/sec | ± 1.63 % | + 306.36 % |
34
+ | undici - request | 10 | 19264.24 req/sec | ± 1.74 % | + 420.03 % |
35
+ | undici - stream | 15 | 20317.29 req/sec | ± 2.13 % | + 448.46 % |
36
+ | undici - dispatch | 10 | 24883.28 req/sec | ± 1.54 % | + 571.72 % |
37
+
38
+ The benchmark is a simple sending data [ example] ( https://github.com/nodejs/undici/blob/main/benchmarks/post-benchmark.js ) using a
39
+ 50 TCP connections with a pipelining depth of 10 running on Node 20.10.0.
40
+
41
+ | _ Tests_ | _ Samples_ | _ Result_ | _ Tolerance_ | _ Difference with slowest_ |
42
+ | :-----------------: | :-------: | :-------------: | :---------: | :-----------------------: |
43
+ | undici - fetch | 20 | 1968.42 req/sec | ± 2.63 % | - |
44
+ | http - no keepalive | 25 | 2330.30 req/sec | ± 2.99 % | + 18.38 % |
45
+ | node-fetch | 20 | 2485.36 req/sec | ± 2.70 % | + 26.26 % |
46
+ | got | 15 | 2787.68 req/sec | ± 2.56 % | + 41.62 % |
47
+ | request | 30 | 2805.10 req/sec | ± 2.59 % | + 42.50 % |
48
+ | axios | 10 | 3040.45 req/sec | ± 1.72 % | + 54.46 % |
49
+ | superagent | 20 | 3358.29 req/sec | ± 2.51 % | + 70.61 % |
50
+ | http - keepalive | 20 | 3477.94 req/sec | ± 2.51 % | + 76.69 % |
51
+ | undici - pipeline | 25 | 3812.61 req/sec | ± 2.80 % | + 93.69 % |
52
+ | undici - request | 10 | 6067.00 req/sec | ± 0.94 % | + 208.22 % |
53
+ | undici - stream | 10 | 6391.61 req/sec | ± 1.98 % | + 224.71 % |
54
+ | undici - dispatch | 10 | 6397.00 req/sec | ± 1.48 % | + 224.98 % |
55
+
38
56
39
57
## Quick Start
40
58
@@ -60,10 +78,14 @@ console.log('trailers', trailers)
60
78
61
79
The ` body ` mixins are the most common way to format the request/response body. Mixins include:
62
80
63
- - [ ` .formData() ` ] ( https://fetch.spec.whatwg.org/#dom-body-formdata )
81
+ - [ ` .arrayBuffer() ` ] ( https://fetch.spec.whatwg.org/#dom-body-arraybuffer )
82
+ - [ ` .blob() ` ] ( https://fetch.spec.whatwg.org/#dom-body-blob )
64
83
- [ ` .json() ` ] ( https://fetch.spec.whatwg.org/#dom-body-json )
65
84
- [ ` .text() ` ] ( https://fetch.spec.whatwg.org/#dom-body-text )
66
85
86
+ > [ !NOTE]
87
+ > The body returned from ` undici.request ` does not implement ` .formData() ` .
88
+
67
89
Example usage:
68
90
69
91
``` js
@@ -123,14 +145,14 @@ Returns a promise with the result of the `Dispatcher.stream` method.
123
145
124
146
Calls ` options.dispatcher.stream(options, factory) ` .
125
147
126
- See [ Dispatcher.stream] ( docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback ) for more details.
148
+ See [ Dispatcher.stream] ( ./ docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback) for more details.
127
149
128
150
### ` undici.pipeline([url, options, ]handler): Duplex `
129
151
130
152
Arguments:
131
153
132
154
* ** url** ` string | URL | UrlObject `
133
- * ** options** [ ` PipelineOptions ` ] ( docs/api/Dispatcher.md#parameter-pipelineoptions )
155
+ * ** options** [ ` PipelineOptions ` ] ( ./ docs/api/Dispatcher.md#parameter-pipelineoptions)
134
156
* ** dispatcher** ` Dispatcher ` - Default: [ getGlobalDispatcher] ( #undicigetglobaldispatcher )
135
157
* ** method** ` String ` - Default: ` PUT ` if ` options.body ` , otherwise ` GET `
136
158
* ** maxRedirections** ` Integer ` - Default: ` 0 `
@@ -140,7 +162,7 @@ Returns: `stream.Duplex`
140
162
141
163
Calls ` options.dispatch.pipeline(options, handler) ` .
142
164
143
- See [ Dispatcher.pipeline] ( docs/api/Dispatcher.md#dispatcherpipelineoptions-handler ) for more details.
165
+ See [ Dispatcher.pipeline] ( ./ docs/api/Dispatcher.md#dispatcherpipelineoptions-handler) for more details.
144
166
145
167
### ` undici.connect([url, options]): Promise `
146
168
@@ -149,7 +171,7 @@ Starts two-way communications with the requested resource using [HTTP CONNECT](h
149
171
Arguments:
150
172
151
173
* ** url** ` string | URL | UrlObject `
152
- * ** options** [ ` ConnectOptions ` ] ( docs/api/Dispatcher.md#parameter-connectoptions )
174
+ * ** options** [ ` ConnectOptions ` ] ( ./ docs/api/Dispatcher.md#parameter-connectoptions)
153
175
* ** dispatcher** ` Dispatcher ` - Default: [ getGlobalDispatcher] ( #undicigetglobaldispatcher )
154
176
* ** maxRedirections** ` Integer ` - Default: ` 0 `
155
177
* ** callback** ` (err: Error | null, data: ConnectData | null) => void ` (optional)
@@ -158,7 +180,7 @@ Returns a promise with the result of the `Dispatcher.connect` method.
158
180
159
181
Calls ` options.dispatch.connect(options) ` .
160
182
161
- See [ Dispatcher.connect] ( docs/api/Dispatcher.md#dispatcherconnectoptions-callback ) for more details.
183
+ See [ Dispatcher.connect] ( ./ docs/api/Dispatcher.md#dispatcherconnectoptions-callback) for more details.
162
184
163
185
### ` undici.fetch(input[, init]): Promise `
164
186
@@ -226,7 +248,7 @@ await fetch('https://example.com', { body: data, method: 'POST', duplex: 'half'
226
248
227
249
- half
228
250
229
- In this implementation of fetch, ` request.duplex ` must be set if ` request.body ` is ` ReadableStream ` or ` Async Iterables ` . And fetch requests are currently always be full duplex. More detail refer to [ Fetch Standard.] ( https://fetch.spec.whatwg.org/#dom-requestinit-duplex )
251
+ In this implementation of fetch, ` request.duplex ` must be set if ` request.body ` is ` ReadableStream ` or ` Async Iterables ` , however, fetch requests are currently always full duplex. For more detail refer to the [ Fetch Standard.] ( https://fetch.spec.whatwg.org/#dom-requestinit-duplex ) .
230
252
231
253
#### ` response.body `
232
254
@@ -297,7 +319,7 @@ Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](h
297
319
Arguments:
298
320
299
321
* ** url** ` string | URL | UrlObject `
300
- * ** options** [ ` UpgradeOptions ` ] ( docs/api/Dispatcher.md#parameter-upgradeoptions )
322
+ * ** options** [ ` UpgradeOptions ` ] ( ./ docs/api/Dispatcher.md#parameter-upgradeoptions)
301
323
* ** dispatcher** ` Dispatcher ` - Default: [ getGlobalDispatcher] ( #undicigetglobaldispatcher )
302
324
* ** maxRedirections** ` Integer ` - Default: ` 0 `
303
325
* ** callback** ` (error: Error | null, data: UpgradeData) => void ` (optional)
@@ -306,7 +328,7 @@ Returns a promise with the result of the `Dispatcher.upgrade` method.
306
328
307
329
Calls ` options.dispatcher.upgrade(options) ` .
308
330
309
- See [ Dispatcher.upgrade] ( docs/api/Dispatcher.md#dispatcherupgradeoptions-callback ) for more details.
331
+ See [ Dispatcher.upgrade] ( ./ docs/api/Dispatcher.md#dispatcherupgradeoptions-callback) for more details.
310
332
311
333
### ` undici.setGlobalDispatcher(dispatcher) `
312
334
@@ -400,9 +422,9 @@ Refs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
400
422
401
423
If you experience problem when connecting to a remote server that is resolved by your DNS servers to a IPv6 (AAAA record)
402
424
first, there are chances that your local router or ISP might have problem connecting to IPv6 networks. In that case
403
- undici will throw an error with code ` UND_ERR_CONNECT_TIMEOUT ` .
425
+ undici will throw an error with code ` UND_ERR_CONNECT_TIMEOUT ` .
404
426
405
- If the target server resolves to both a IPv6 and IPv4 (A records) address and you are using a compatible Node version
427
+ If the target server resolves to both a IPv6 and IPv4 (A records) address and you are using a compatible Node version
406
428
(18.3.0 and above), you can fix the problem by providing the ` autoSelectFamily ` option (support by both ` undici.request `
407
429
and ` undici.Agent ` ) which will enable the family autoselection algorithm when establishing the connection.
408
430
0 commit comments