Skip to content

Commit 8464ab7

Browse files
docs: add Getting Started guide (#5371)
1 parent ba12bb1 commit 8464ab7

2 files changed

Lines changed: 279 additions & 0 deletions

File tree

docs/docs/GettingStarted.md

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# Getting Started
2+
3+
## Installation
4+
5+
```bash
6+
npm install undici
7+
```
8+
9+
## Fetch
10+
11+
The quickest way to get started is with `fetch`, which follows the
12+
[Fetch Standard](https://fetch.spec.whatwg.org/) and works the same way as
13+
the browser API:
14+
15+
```js
16+
import { fetch } from 'undici'
17+
18+
const res = await fetch('https://example.com')
19+
const data = await res.json()
20+
console.log(data)
21+
```
22+
23+
### Using the Request object
24+
25+
undici also exports a `Request` class that follows the Fetch Standard:
26+
27+
```js
28+
import { fetch, Request } from 'undici'
29+
30+
const req = new Request('https://example.com', {
31+
method: 'POST',
32+
headers: { 'content-type': 'application/json' },
33+
body: JSON.stringify({ hello: 'world' })
34+
})
35+
const res = await fetch(req)
36+
console.log(res.status)
37+
```
38+
39+
### Streaming the response
40+
41+
`res.body` is a web `ReadableStream`. Use `pipeline` from
42+
`node:stream/promises` to stream it to a file:
43+
44+
```js
45+
import { fetch } from 'undici'
46+
import { pipeline } from 'node:stream/promises'
47+
import { createWriteStream } from 'node:fs'
48+
49+
const res = await fetch('https://example.com/large-file.zip')
50+
await pipeline(res.body, createWriteStream('./file.zip'))
51+
```
52+
53+
> Always consume or cancel the response body. In Node.js, garbage collection
54+
> is not aggressive enough to release connections promptly, so leaving a body
55+
> unread can cause connection leaks and stalled requests. See
56+
> [Specification Compliance - Garbage Collection](/docs/#garbage-collection)
57+
> for details.
58+
59+
For more on `fetch`, see [API Reference: Fetch](/docs/docs/api/Fetch.md).
60+
61+
## Dispatchers: Connection reuse and pooling
62+
63+
By default, `fetch`, `request`, `stream`, and `pipeline` create a new connection
64+
for each call. For applications that make many requests to the same origin,
65+
this is wasteful. undici provides **dispatchers** that manage connections
66+
internally.
67+
68+
### `Agent` — for requests to multiple origins
69+
70+
`Agent` is the most general-purpose dispatcher. It pools connections per-origin
71+
and is the recommended default for most applications. Use it with
72+
`setGlobalDispatcher` to affect all undici calls globally:
73+
74+
```js
75+
import { Agent, setGlobalDispatcher, fetch } from 'undici'
76+
77+
const agent = new Agent({
78+
keepAliveTimeout: 30_000,
79+
keepAliveMaxTimeout: 600_000
80+
})
81+
setGlobalDispatcher(agent)
82+
83+
// All subsequent fetch/request/stream/pipeline calls reuse connections
84+
const res = await fetch('https://api.example.com/data')
85+
```
86+
87+
You can also pass a dispatcher per-request:
88+
89+
```js
90+
await fetch('https://api.example.com/data', { dispatcher: agent })
91+
```
92+
93+
### `Pool` — for requests to a single origin
94+
95+
`Pool` manages a fixed set of connections to one origin. It gives you explicit
96+
control over concurrency:
97+
98+
```js
99+
import { Pool, request } from 'undici'
100+
101+
const pool = new Pool('https://api.example.com', { connections: 10 })
102+
103+
const { body } = await request('https://api.example.com/data', {
104+
dispatcher: pool
105+
})
106+
const data = await body.json()
107+
108+
pool.close()
109+
```
110+
111+
### `Client` — for a single connection
112+
113+
`Client` maps to a single TCP connection. It supports pipelining (sending
114+
multiple requests before responses arrive):
115+
116+
```js
117+
import { Client } from 'undici'
118+
119+
const client = new Client('https://api.example.com', {
120+
pipelining: 5
121+
})
122+
123+
const { body } = await client.request({ path: '/', method: 'GET' })
124+
await body.dump()
125+
126+
client.close()
127+
```
128+
129+
For more on dispatcher options and lifecycle, see:
130+
- [API Reference: Agent](/docs/docs/api/Agent.md)
131+
- [API Reference: Pool](/docs/docs/api/Pool.md)
132+
- [API Reference: Client](/docs/docs/api/Client.md)
133+
134+
## Timeouts
135+
136+
undici applies timeouts at two levels:
137+
138+
- **`headersTimeout`** — time to wait for response headers (default: 300s).
139+
- **`bodyTimeout`** — time between consecutive body chunks (default: 300s).
140+
141+
Set these on the dispatcher or per-request:
142+
143+
```js
144+
import { Agent, setGlobalDispatcher } from 'undici'
145+
146+
const agent = new Agent({
147+
headersTimeout: 5_000,
148+
bodyTimeout: 30_000
149+
})
150+
151+
setGlobalDispatcher(agent)
152+
```
153+
154+
Timeout errors are thrown as `HeadersTimeoutError` and `BodyTimeoutError`.
155+
See [API Reference: Errors](/docs/docs/api/Errors.md) for the full list.
156+
157+
## Error handling
158+
159+
undici exposes structured errors via `error.code`:
160+
161+
```js
162+
import { request, errors } from 'undici'
163+
164+
try {
165+
const { body } = await request('https://example.com')
166+
await body.json()
167+
} catch (err) {
168+
switch (err.code) {
169+
case errors.ConnectTimeoutError.code:
170+
console.error('Connection timed out')
171+
break
172+
case errors.HeadersTimeoutError.code:
173+
console.error('Headers timed out')
174+
break
175+
case errors.BodyTimeoutError.code:
176+
console.error('Body timed out')
177+
break
178+
case errors.RequestAbortedError.code:
179+
console.error('Request was aborted')
180+
break
181+
default:
182+
console.error(err)
183+
}
184+
}
185+
```
186+
187+
### Aborting requests
188+
189+
```js
190+
import { request } from 'undici'
191+
192+
const ac = new AbortController()
193+
194+
setTimeout(() => ac.abort(), 1000)
195+
196+
try {
197+
const { body } = await request('https://example.com', {
198+
signal: ac.signal
199+
})
200+
await body.dump()
201+
} catch (err) {
202+
console.error(err.code) // UND_ERR_ABORTED
203+
}
204+
```
205+
206+
## Common patterns
207+
208+
### Proxies
209+
210+
Use `ProxyAgent` for HTTP(S) proxies, or `EnvHttpProxyAgent` to pick up
211+
proxy settings from environment variables:
212+
213+
```js
214+
import { ProxyAgent, setGlobalDispatcher } from 'undici'
215+
216+
const proxy = new ProxyAgent('http://proxy.internal:8080')
217+
setGlobalDispatcher(proxy)
218+
```
219+
220+
See [Best Practices: Proxy](/docs/docs/best-practices/proxy.md) and
221+
[API Reference: ProxyAgent](/docs/docs/api/ProxyAgent.md).
222+
223+
### Mocking in tests
224+
225+
```js
226+
import { MockAgent, setGlobalDispatcher, request } from 'undici'
227+
228+
const mockAgent = new MockAgent()
229+
setGlobalDispatcher(mockAgent)
230+
231+
const mockPool = mockAgent.get('https://api.example.com')
232+
mockPool.intercept({ path: '/users' }).reply(200, [{ id: 1 }])
233+
234+
const { body } = await request('https://api.example.com/users')
235+
console.log(await body.json())
236+
```
237+
238+
See [Best Practices: Mocking Request](/docs/docs/best-practices/mocking-request.md)
239+
and [API Reference: MockAgent](/docs/docs/api/MockAgent.md).
240+
241+
### Testing with undici
242+
243+
For test suites, set short keep-alive timeouts to avoid slow teardowns:
244+
245+
```js
246+
import { Agent, setGlobalDispatcher } from 'undici'
247+
248+
const agent = new Agent({
249+
keepAliveTimeout: 10,
250+
keepAliveMaxTimeout: 10
251+
})
252+
setGlobalDispatcher(agent)
253+
```
254+
255+
See [Best Practices: Writing Tests](/docs/docs/best-practices/writing-tests.md).
256+
257+
### Customizing the global fetch
258+
259+
You can override Node.js's built-in globals with `install()`:
260+
261+
```js
262+
import { install } from 'undici'
263+
264+
install()
265+
266+
// Global fetch, Headers, Response, Request, and FormData
267+
// now come from undici, not the Node.js bundle
268+
const res = await fetch('https://example.com')
269+
```
270+
271+
See [API Reference: Global Installation](/docs/docs/api/GlobalInstallation.md).
272+
273+
## Further reading
274+
275+
- [Undici vs. Built-in Fetch](/docs/docs/best-practices/undici-vs-builtin-fetch.md)
276+
when to install undici vs using Node.js built-in fetch
277+
- [API Reference](/docs/docs/api/Dispatcher.md) — full dispatcher API documentation
278+
- [Examples](/docs/examples/) — runnable code examples

docs/docsify/sidebar.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<!-- Sidebar for Docsify -->
22

33
* [**Home**](/ "Node.js Undici")
4+
* [Getting Started](/docs/docs/GettingStarted.md "Getting Started with Undici")
45
* API
56
* [Dispatcher](/docs/docs/api/Dispatcher.md "Undici API - Dispatcher")
67
* [Client](/docs/docs/api/Client.md "Undici API - Client")

0 commit comments

Comments
 (0)