0
# Connection Management
1
2
Dispatcher classes for managing HTTP connections at different scales, from single connections to multi-origin load balancing.
3
4
## Capabilities
5
6
### Client
7
8
Basic HTTP/1.1 client for single TCP/TLS connections. Ideal for simple use cases requiring connection to a single origin.
9
10
```javascript { .api }
11
/**
12
* HTTP client for single TCP/TLS connections
13
*/
14
class Client extends Dispatcher {
15
constructor(url: string | URL, options?: Client.Options);
16
17
// Inherited from Dispatcher
18
request(options: RequestOptions): Promise<ResponseData>;
19
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
20
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
21
connect(options: ConnectOptions): Promise<ConnectData>;
22
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
23
close(): Promise<void>;
24
destroy(err?: Error): Promise<void>;
25
}
26
27
interface Client.Options {
28
bodyTimeout?: number;
29
headersTimeout?: number;
30
keepAliveMaxTimeout?: number;
31
keepAliveTimeout?: number;
32
keepAliveTimeoutThreshold?: number;
33
maxHeaderSize?: number;
34
maxResponseSize?: number;
35
pipelining?: number;
36
connect?: ConnectOptions | ConnectFunction;
37
strictContentLength?: boolean;
38
}
39
```
40
41
**Usage Examples:**
42
43
```javascript
44
import { Client } from 'undici';
45
46
// Basic client setup
47
const client = new Client('https://api.example.com');
48
49
// Make requests
50
const { statusCode, body } = await client.request({
51
path: '/users',
52
method: 'GET'
53
});
54
55
const users = await body.json();
56
57
// Configure client options
58
const configuredClient = new Client('https://api.example.com', {
59
keepAliveTimeout: 10000,
60
pipelining: 1,
61
bodyTimeout: 5000
62
});
63
64
// Always close when done
65
await client.close();
66
```
67
68
### Pool
69
70
Connection pool for managing multiple clients to the same origin. Provides automatic connection pooling and lifecycle management.
71
72
```javascript { .api }
73
/**
74
* Connection pool for single origin with multiple connections
75
*/
76
class Pool extends Dispatcher {
77
constructor(url: string | URL, options?: Pool.Options);
78
79
// Inherited from Dispatcher
80
request(options: RequestOptions): Promise<ResponseData>;
81
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
82
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
83
connect(options: ConnectOptions): Promise<ConnectData>;
84
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
85
close(): Promise<void>;
86
destroy(err?: Error): Promise<void>;
87
}
88
89
interface Pool.Options extends Client.Options {
90
connections?: number;
91
factory?: (origin: URL, opts: object) => Dispatcher;
92
}
93
```
94
95
**Usage Examples:**
96
97
```javascript
98
import { Pool } from 'undici';
99
100
// Pool with multiple connections
101
const pool = new Pool('https://api.example.com', {
102
connections: 10,
103
pipelining: 1
104
});
105
106
// Make concurrent requests efficiently
107
const promises = Array.from({ length: 100 }, (_, i) =>
108
pool.request({ path: `/users/${i}` })
109
);
110
111
const responses = await Promise.all(promises);
112
113
// Pool automatically manages connections
114
await pool.close();
115
```
116
117
### BalancedPool
118
119
Load balancer across multiple upstream servers. Distributes requests across multiple origins with automatic failover.
120
121
```javascript { .api }
122
/**
123
* Load balancer across multiple upstream servers
124
*/
125
class BalancedPool extends Dispatcher {
126
constructor(upstreams: string[] | URL[], options?: BalancedPool.Options);
127
128
addUpstream(upstream: string | URL): BalancedPool;
129
removeUpstream(upstream: string | URL): BalancedPool;
130
upstreams: Array<string>;
131
132
// Inherited from Dispatcher
133
request(options: RequestOptions): Promise<ResponseData>;
134
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
135
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
136
connect(options: ConnectOptions): Promise<ConnectData>;
137
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
138
close(): Promise<void>;
139
destroy(err?: Error): Promise<void>;
140
}
141
142
interface BalancedPool.Options extends Pool.Options {
143
factory?: (origin: URL, opts: object) => Dispatcher;
144
}
145
```
146
147
**Usage Examples:**
148
149
```javascript
150
import { BalancedPool } from 'undici';
151
152
// Create load balancer with multiple upstreams
153
const balancer = new BalancedPool([
154
'https://api1.example.com',
155
'https://api2.example.com',
156
'https://api3.example.com'
157
]);
158
159
// Requests are automatically distributed
160
const { body } = await balancer.request({ path: '/users' });
161
const users = await body.json();
162
163
// Add/remove upstreams dynamically
164
balancer.addUpstream('https://api4.example.com');
165
balancer.removeUpstream('https://api1.example.com');
166
167
await balancer.close();
168
```
169
170
### Agent
171
172
Agent for managing multiple pools across different origins. Provides automatic origin-based routing and connection pooling.
173
174
```javascript { .api }
175
/**
176
* Agent for managing multiple pools across different origins
177
*/
178
class Agent extends Dispatcher {
179
constructor(options?: Agent.Options);
180
181
// Inherited from Dispatcher
182
request(options: RequestOptions): Promise<ResponseData>;
183
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
184
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
185
connect(options: ConnectOptions): Promise<ConnectData>;
186
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
187
close(): Promise<void>;
188
destroy(err?: Error): Promise<void>;
189
}
190
191
interface Agent.Options {
192
factory?: (origin: URL, opts: object) => Dispatcher;
193
maxRedirections?: number;
194
interceptors?: {
195
Agent?: readonly DispatcherComposeInterceptor[];
196
Client?: readonly DispatcherComposeInterceptor[];
197
};
198
}
199
```
200
201
**Usage Examples:**
202
203
```javascript
204
import { Agent } from 'undici';
205
206
// Create agent for multiple origins
207
const agent = new Agent({
208
factory: (origin, opts) => {
209
return new Pool(origin, { ...opts, connections: 5 });
210
}
211
});
212
213
// Make requests to different origins
214
const [users, posts] = await Promise.all([
215
agent.request({
216
origin: 'https://users-api.example.com',
217
path: '/users'
218
}),
219
agent.request({
220
origin: 'https://posts-api.example.com',
221
path: '/posts'
222
})
223
]);
224
225
// Agent automatically manages pools per origin
226
await agent.close();
227
```
228
229
### ProxyAgent
230
231
HTTP proxy agent for routing requests through proxy servers.
232
233
```javascript { .api }
234
/**
235
* HTTP proxy agent for routing requests through proxies
236
*/
237
class ProxyAgent extends Dispatcher {
238
constructor(options: ProxyAgent.Options | string);
239
240
// Inherited from Dispatcher
241
request(options: RequestOptions): Promise<ResponseData>;
242
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
243
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
244
connect(options: ConnectOptions): Promise<ConnectData>;
245
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
246
close(): Promise<void>;
247
destroy(err?: Error): Promise<void>;
248
}
249
250
interface ProxyAgent.Options {
251
uri: string;
252
token?: string;
253
auth?: string;
254
factory?: (origin: URL, opts: object) => Dispatcher;
255
requestTls?: BuildOptions;
256
proxyTls?: BuildOptions;
257
interceptors?: {
258
ProxyAgent?: readonly DispatcherComposeInterceptor[];
259
};
260
}
261
```
262
263
**Usage Examples:**
264
265
```javascript
266
import { ProxyAgent } from 'undici';
267
268
// HTTP proxy
269
const proxyAgent = new ProxyAgent('http://proxy.example.com:8080');
270
271
// HTTPS proxy with authentication
272
const authProxyAgent = new ProxyAgent({
273
uri: 'https://proxy.example.com:8080',
274
token: 'Bearer token123',
275
auth: 'user:password'
276
});
277
278
// Use proxy for requests
279
const { body } = await proxyAgent.request({
280
origin: 'https://api.example.com',
281
path: '/data'
282
});
283
284
await proxyAgent.close();
285
```
286
287
### EnvHttpProxyAgent
288
289
Environment-based HTTP proxy agent that automatically uses HTTP_PROXY and HTTPS_PROXY environment variables.
290
291
```javascript { .api }
292
/**
293
* Environment-based HTTP proxy agent using env vars
294
*/
295
class EnvHttpProxyAgent extends Dispatcher {
296
constructor(options?: EnvHttpProxyAgent.Options);
297
298
// Inherited from Dispatcher
299
request(options: RequestOptions): Promise<ResponseData>;
300
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
301
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
302
connect(options: ConnectOptions): Promise<ConnectData>;
303
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
304
close(): Promise<void>;
305
destroy(err?: Error): Promise<void>;
306
}
307
308
interface EnvHttpProxyAgent.Options {
309
factory?: (origin: URL, opts: object) => Dispatcher;
310
interceptors?: {
311
EnvHttpProxyAgent?: readonly DispatcherComposeInterceptor[];
312
};
313
}
314
```
315
316
**Usage Examples:**
317
318
```javascript
319
import { EnvHttpProxyAgent } from 'undici';
320
321
// Set environment variables
322
process.env.HTTP_PROXY = 'http://proxy.example.com:8080';
323
process.env.HTTPS_PROXY = 'https://secure-proxy.example.com:8080';
324
process.env.NO_PROXY = 'localhost,127.0.0.1,.internal';
325
326
// Agent automatically uses environment settings
327
const envAgent = new EnvHttpProxyAgent();
328
329
const { body } = await envAgent.request({
330
origin: 'https://api.example.com',
331
path: '/data'
332
});
333
334
await envAgent.close();
335
```
336
337
### RetryAgent
338
339
Agent with automatic retry capabilities for handling transient failures.
340
341
```javascript { .api }
342
/**
343
* Agent with automatic retry capabilities
344
*/
345
class RetryAgent extends Dispatcher {
346
constructor(dispatcher: Dispatcher, options?: RetryAgent.Options);
347
348
// Inherited from Dispatcher
349
request(options: RequestOptions): Promise<ResponseData>;
350
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
351
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
352
connect(options: ConnectOptions): Promise<ConnectData>;
353
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
354
close(): Promise<void>;
355
destroy(err?: Error): Promise<void>;
356
}
357
358
interface RetryAgent.Options {
359
retry?: RetryOptions;
360
interceptors?: {
361
RetryAgent?: readonly DispatcherComposeInterceptor[];
362
};
363
}
364
365
interface RetryOptions {
366
retry?: (err: Error, context: RetryContext) => number | null;
367
maxRetries?: number;
368
maxTimeout?: number;
369
minTimeout?: number;
370
timeoutFactor?: number;
371
retryAfter?: boolean;
372
methods?: string[];
373
statusCodes?: number[];
374
errorCodes?: string[];
375
}
376
```
377
378
**Usage Examples:**
379
380
```javascript
381
import { RetryAgent, Pool } from 'undici';
382
383
// Create retry agent with custom retry logic
384
const retryAgent = new RetryAgent(
385
new Pool('https://api.example.com'),
386
{
387
retry: (err, { attempt, maxRetries }) => {
388
if (attempt >= maxRetries) return null;
389
390
// Exponential backoff
391
return Math.min(1000 * (2 ** attempt), 10000);
392
},
393
maxRetries: 3,
394
methods: ['GET', 'HEAD', 'OPTIONS'],
395
statusCodes: [408, 413, 429, 500, 502, 503, 504]
396
}
397
);
398
399
// Requests automatically retry on failure
400
const { body } = await retryAgent.request({ path: '/unreliable-endpoint' });
401
402
await retryAgent.close();
403
```
404
405
### H2CClient
406
407
HTTP/2 cleartext client for HTTP/2 connections without TLS.
408
409
```javascript { .api }
410
/**
411
* HTTP/2 cleartext client
412
*/
413
class H2CClient extends Dispatcher {
414
constructor(url: string | URL, options?: H2CClient.Options);
415
416
// Inherited from Dispatcher
417
request(options: RequestOptions): Promise<ResponseData>;
418
stream(options: RequestOptions, factory: StreamFactory): Promise<StreamData>;
419
pipeline(options: PipelineOptions, handler: PipelineHandler): Duplex;
420
connect(options: ConnectOptions): Promise<ConnectData>;
421
upgrade(options: UpgradeOptions): Promise<UpgradeData>;
422
close(): Promise<void>;
423
destroy(err?: Error): Promise<void>;
424
}
425
426
interface H2CClient.Options {
427
maxConcurrentStreams?: number;
428
maxHeaderListSize?: number;
429
initialWindowSize?: number;
430
maxFrameSize?: number;
431
}
432
```
433
434
**Usage Examples:**
435
436
```javascript
437
import { H2CClient } from 'undici';
438
439
// HTTP/2 cleartext connection
440
const h2cClient = new H2CClient('http://h2c-server.example.com');
441
442
// Make HTTP/2 requests
443
const { body } = await h2cClient.request({
444
path: '/api/data',
445
method: 'GET'
446
});
447
448
const data = await body.json();
449
await h2cClient.close();
450
```
451
452
### Connection Builder
453
454
Utility for creating custom connection functions with TLS and socket options.
455
456
```javascript { .api }
457
/**
458
* Build a custom connector function for establishing connections
459
* @param options - Connection configuration options
460
* @returns Connector function for creating connections
461
*/
462
function buildConnector(options?: ConnectorOptions): Connector;
463
464
type Connector = (options: ConnectOptions, callback: ConnectCallback) => void;
465
466
interface ConnectorOptions {
467
maxCachedSessions?: number;
468
socketPath?: string;
469
timeout?: number;
470
keepAlive?: boolean;
471
keepAliveInitialDelay?: number;
472
allowH2?: boolean;
473
maxHeaderListSize?: number;
474
maxConcurrentStreams?: number;
475
autoSelectFamily?: boolean;
476
autoSelectFamilyAttemptTimeout?: number;
477
}
478
479
interface ConnectOptions {
480
hostname: string;
481
host?: string;
482
port: number;
483
servername?: string;
484
httpSocket?: any;
485
}
486
487
type ConnectCallback = (err: Error | null, socket: any) => void;
488
```
489
490
**Usage Examples:**
491
492
```javascript
493
import { buildConnector, Client } from 'undici';
494
495
// Create a custom connector with specific options
496
const connector = buildConnector({
497
timeout: 30000,
498
keepAlive: true,
499
keepAliveInitialDelay: 1000,
500
allowH2: true,
501
autoSelectFamily: true
502
});
503
504
// Use connector with a client
505
const client = new Client('https://api.example.com', {
506
connect: connector
507
});
508
509
// Custom TLS connector
510
const tlsConnector = buildConnector({
511
timeout: 60000,
512
keepAlive: true,
513
maxCachedSessions: 100
514
});
515
516
// Use with Agent for multiple origins
517
const agent = new Agent({
518
connect: tlsConnector,
519
keepAliveTimeout: 30000
520
});
521
```
522
523
## Types
524
525
### Connection Types
526
527
```javascript { .api }
528
type ConnectFunction = (options: ConnectOptions) => Promise<Duplex>;
529
530
interface ConnectOptions {
531
hostname: string;
532
host?: string;
533
port: number;
534
servername?: string;
535
timeout?: number;
536
}
537
538
interface BuildOptions {
539
ca?: string | Buffer | Array<string | Buffer>;
540
cert?: string | Buffer | Array<string | Buffer>;
541
key?: string | Buffer | Array<string | Buffer>;
542
secureOptions?: number;
543
rejectUnauthorized?: boolean;
544
}
545
```