0
# Global Configuration
1
2
Global settings for default dispatchers, origins, and Web API installation to configure undici behavior across your entire application.
3
4
## Capabilities
5
6
### Global Dispatcher Management
7
8
Configure a default dispatcher that will be used for all undici requests when no specific dispatcher is provided.
9
10
```javascript { .api }
11
/**
12
* Set global dispatcher for all requests
13
* @param dispatcher - Dispatcher instance to use globally
14
*/
15
function setGlobalDispatcher(dispatcher: Dispatcher): void;
16
17
/**
18
* Get current global dispatcher
19
* @returns Current global dispatcher instance
20
*/
21
function getGlobalDispatcher(): Dispatcher;
22
```
23
24
**Usage Examples:**
25
26
```javascript
27
import { setGlobalDispatcher, getGlobalDispatcher, Agent, Pool } from 'undici';
28
29
// Set a global agent with custom configuration
30
const globalAgent = new Agent({
31
factory: (origin, opts) => {
32
return new Pool(origin, {
33
...opts,
34
connections: 10,
35
keepAliveTimeout: 60000,
36
keepAliveMaxTimeout: 600000
37
});
38
}
39
});
40
41
setGlobalDispatcher(globalAgent);
42
43
// All subsequent requests use the global agent
44
const response1 = await fetch('https://api.example.com/users');
45
const response2 = await fetch('https://another-api.example.com/data');
46
47
// Check current global dispatcher
48
const currentDispatcher = getGlobalDispatcher();
49
console.log(currentDispatcher === globalAgent); // true
50
51
// Configure global agent with interceptors
52
import { interceptors } from 'undici';
53
54
const enhancedAgent = new Agent()
55
.compose(
56
interceptors.retry({ maxRetries: 3 }),
57
interceptors.redirect({ maxRedirections: 5 }),
58
interceptors.decompress()
59
);
60
61
setGlobalDispatcher(enhancedAgent);
62
63
// All requests now have retry, redirect, and decompression
64
const response = await fetch('https://api.example.com/data');
65
```
66
67
### Global Origin Management
68
69
Set a global origin for the fetch API to resolve relative URLs consistently across your application.
70
71
```javascript { .api }
72
/**
73
* Set global origin for fetch API
74
* @param origin - Base origin URL for resolving relative URLs
75
*/
76
function setGlobalOrigin(origin: string | URL): void;
77
78
/**
79
* Get current global origin
80
* @returns Current global origin or undefined
81
*/
82
function getGlobalOrigin(): string | undefined;
83
```
84
85
**Usage Examples:**
86
87
```javascript
88
import { setGlobalOrigin, getGlobalOrigin, fetch } from 'undici';
89
90
// Set global origin for API base URL
91
setGlobalOrigin('https://api.example.com');
92
93
// Relative URLs are resolved against the global origin
94
const response1 = await fetch('/users'); // → https://api.example.com/users
95
const response2 = await fetch('/posts/123'); // → https://api.example.com/posts/123
96
const response3 = await fetch('./data.json'); // → https://api.example.com/data.json
97
98
// Absolute URLs override the global origin
99
const response4 = await fetch('https://other-api.com/data'); // → https://other-api.com/data
100
101
// Check current global origin
102
console.log(getGlobalOrigin()); // 'https://api.example.com'
103
104
// Update global origin for different environments
105
const isProduction = process.env.NODE_ENV === 'production';
106
const apiOrigin = isProduction
107
? 'https://api.production.com'
108
: 'https://api.development.com';
109
110
setGlobalOrigin(apiOrigin);
111
112
// Environment-specific API calls
113
const userData = await fetch('/user/profile');
114
const settings = await fetch('/user/settings');
115
```
116
117
### Global Web API Installation
118
119
Install undici's Web API implementations globally to make them available throughout your application without imports.
120
121
```javascript { .api }
122
/**
123
* Install Web APIs globally on globalThis
124
* Makes fetch, Headers, Request, Response, FormData, WebSocket, etc. available globally
125
*/
126
function install(): void;
127
```
128
129
**Usage Examples:**
130
131
```javascript
132
import { install } from 'undici';
133
134
// Install all Web APIs globally
135
install();
136
137
// Now you can use Web APIs without importing
138
// These are now available globally:
139
140
// Fetch API
141
const response = await fetch('https://api.example.com/data');
142
const data = await response.json();
143
144
// Headers API
145
const headers = new Headers({
146
'Content-Type': 'application/json',
147
'Authorization': 'Bearer token123'
148
});
149
150
// Request/Response API
151
const request = new Request('https://api.example.com/users', {
152
method: 'POST',
153
headers,
154
body: JSON.stringify({ name: 'Alice' })
155
});
156
157
const customResponse = new Response(JSON.stringify({ success: true }), {
158
status: 201,
159
headers: { 'content-type': 'application/json' }
160
});
161
162
// FormData API
163
const formData = new FormData();
164
formData.append('file', fileBuffer, 'document.pdf');
165
formData.append('description', 'Important document');
166
167
// WebSocket API
168
const ws = new WebSocket('wss://api.example.com/socket');
169
ws.onopen = () => console.log('WebSocket connected');
170
ws.onmessage = (event) => console.log('Message:', event.data);
171
172
// EventSource API
173
const eventSource = new EventSource('https://api.example.com/events');
174
eventSource.onmessage = (event) => {
175
console.log('Event:', JSON.parse(event.data));
176
};
177
178
// WebSocket Events
179
ws.addEventListener('close', (event) => {
180
if (event instanceof CloseEvent) {
181
console.log(`WebSocket closed: ${event.code} ${event.reason}`);
182
}
183
});
184
```
185
186
## Environment-Specific Configuration
187
188
### Development vs Production Setup
189
190
```javascript
191
import {
192
setGlobalDispatcher,
193
setGlobalOrigin,
194
install,
195
Agent,
196
interceptors,
197
cacheStores
198
} from 'undici';
199
200
function configureUndici() {
201
const isDevelopment = process.env.NODE_ENV === 'development';
202
const isProduction = process.env.NODE_ENV === 'production';
203
204
// Install Web APIs globally
205
install();
206
207
// Set environment-specific API origin
208
const apiOrigin = process.env.API_BASE_URL || (
209
isProduction
210
? 'https://api.production.com'
211
: 'http://localhost:3001'
212
);
213
setGlobalOrigin(apiOrigin);
214
215
// Configure global dispatcher based on environment
216
const interceptorChain = [];
217
218
// Always enable decompression
219
interceptorChain.push(interceptors.decompress());
220
221
// Enable caching in production
222
if (isProduction) {
223
interceptorChain.push(interceptors.cache({
224
store: new cacheStores.MemoryCacheStore(),
225
methods: ['GET', 'HEAD'],
226
cacheByDefault: 300 // 5 minutes
227
}));
228
}
229
230
// Enable request logging in development
231
if (isDevelopment) {
232
interceptorChain.push(interceptors.dump({
233
request: true,
234
response: true,
235
requestHeaders: true,
236
responseHeaders: true,
237
logger: console.log
238
}));
239
}
240
241
// Always enable retries and redirects
242
interceptorChain.push(
243
interceptors.retry({
244
maxRetries: isProduction ? 3 : 1,
245
methods: ['GET', 'HEAD', 'OPTIONS'],
246
statusCodes: [408, 413, 429, 500, 502, 503, 504]
247
}),
248
interceptors.redirect({ maxRedirections: 5 })
249
);
250
251
// Create and set global agent
252
const globalAgent = new Agent({
253
factory: (origin, opts) => {
254
return new Pool(origin, {
255
...opts,
256
connections: isProduction ? 10 : 5,
257
keepAliveTimeout: 60000,
258
keepAliveMaxTimeout: 600000,
259
bodyTimeout: 30000,
260
headersTimeout: 10000
261
});
262
}
263
}).compose(...interceptorChain);
264
265
setGlobalDispatcher(globalAgent);
266
267
console.log(`Undici configured for ${process.env.NODE_ENV} environment`);
268
console.log(`API Origin: ${apiOrigin}`);
269
}
270
271
// Call during application startup
272
configureUndici();
273
```
274
275
### Testing Configuration
276
277
```javascript
278
import {
279
setGlobalDispatcher,
280
MockAgent,
281
install
282
} from 'undici';
283
284
function configureUndiciForTesting() {
285
// Install Web APIs for test compatibility
286
install();
287
288
// Create mock agent for testing
289
const mockAgent = new MockAgent();
290
291
// Disable real network connections in tests
292
mockAgent.disableNetConnect();
293
294
// Allow connections to test servers if needed
295
if (process.env.TEST_SERVER_URL) {
296
mockAgent.enableNetConnect(process.env.TEST_SERVER_URL);
297
}
298
299
// Set as global dispatcher
300
setGlobalDispatcher(mockAgent);
301
302
return mockAgent;
303
}
304
305
// In test setup
306
const mockAgent = configureUndiciForTesting();
307
308
// In individual tests
309
const mockPool = mockAgent.get('https://api.example.com');
310
mockPool.intercept({ path: '/users', method: 'GET' })
311
.reply(200, [{ id: 1, name: 'Test User' }]);
312
```
313
314
### Proxy Configuration
315
316
```javascript
317
import {
318
setGlobalDispatcher,
319
ProxyAgent,
320
EnvHttpProxyAgent
321
} from 'undici';
322
323
function configureProxy() {
324
// Option 1: Explicit proxy configuration
325
if (process.env.HTTP_PROXY_URL) {
326
const proxyAgent = new ProxyAgent({
327
uri: process.env.HTTP_PROXY_URL,
328
auth: process.env.HTTP_PROXY_AUTH, // username:password
329
token: process.env.HTTP_PROXY_TOKEN
330
});
331
setGlobalDispatcher(proxyAgent);
332
console.log(`Using explicit proxy: ${process.env.HTTP_PROXY_URL}`);
333
return;
334
}
335
336
// Option 2: Environment-based proxy (HTTP_PROXY, HTTPS_PROXY, NO_PROXY)
337
if (process.env.HTTP_PROXY || process.env.HTTPS_PROXY) {
338
const envProxyAgent = new EnvHttpProxyAgent();
339
setGlobalDispatcher(envProxyAgent);
340
console.log('Using environment-based proxy configuration');
341
return;
342
}
343
344
console.log('No proxy configuration found');
345
}
346
347
// Configure proxy during application startup
348
configureProxy();
349
```
350
351
### Advanced Global Configuration
352
353
```javascript
354
import {
355
setGlobalDispatcher,
356
setGlobalOrigin,
357
install,
358
Agent,
359
Pool,
360
interceptors,
361
buildConnector,
362
cacheStores
363
} from 'undici';
364
import { readFileSync } from 'fs';
365
366
function advancedUndiciConfiguration() {
367
// Install Web APIs
368
install();
369
370
// Custom TLS configuration
371
const tlsOptions = {
372
ca: process.env.CUSTOM_CA_CERT ? readFileSync(process.env.CUSTOM_CA_CERT) : undefined,
373
cert: process.env.CLIENT_CERT ? readFileSync(process.env.CLIENT_CERT) : undefined,
374
key: process.env.CLIENT_KEY ? readFileSync(process.env.CLIENT_KEY) : undefined,
375
rejectUnauthorized: process.env.NODE_ENV === 'production'
376
};
377
378
// Custom connector with TLS options
379
const connector = buildConnector(tlsOptions);
380
381
// Advanced agent configuration
382
const agent = new Agent({
383
factory: (origin, opts) => {
384
const poolOptions = {
385
...opts,
386
connections: parseInt(process.env.HTTP_POOL_SIZE) || 10,
387
keepAliveTimeout: parseInt(process.env.HTTP_KEEP_ALIVE_TIMEOUT) || 60000,
388
keepAliveMaxTimeout: parseInt(process.env.HTTP_KEEP_ALIVE_MAX_TIMEOUT) || 600000,
389
bodyTimeout: parseInt(process.env.HTTP_BODY_TIMEOUT) || 30000,
390
headersTimeout: parseInt(process.env.HTTP_HEADERS_TIMEOUT) || 10000,
391
maxHeaderSize: parseInt(process.env.HTTP_MAX_HEADER_SIZE) || 16384,
392
connect: connector
393
};
394
395
return new Pool(origin, poolOptions);
396
},
397
interceptors: {
398
Agent: [
399
// Global interceptors applied to all requests
400
interceptors.dns({
401
maxItems: 100,
402
maxTtl: 300000 // 5 minutes DNS cache
403
})
404
]
405
}
406
});
407
408
// Compose with additional interceptors
409
const configuredAgent = agent.compose(
410
// Response caching
411
interceptors.cache({
412
store: process.env.REDIS_URL
413
? new CustomRedisCacheStore(process.env.REDIS_URL)
414
: new cacheStores.MemoryCacheStore(),
415
methods: ['GET', 'HEAD'],
416
cacheByDefault: 300
417
}),
418
419
// Request/response compression
420
interceptors.decompress(),
421
422
// Automatic redirects
423
interceptors.redirect({
424
maxRedirections: parseInt(process.env.HTTP_MAX_REDIRECTS) || 5
425
}),
426
427
// Retry logic
428
interceptors.retry({
429
maxRetries: parseInt(process.env.HTTP_MAX_RETRIES) || 3,
430
maxTimeout: parseInt(process.env.HTTP_RETRY_MAX_TIMEOUT) || 30000,
431
methods: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'],
432
statusCodes: [408, 413, 429, 500, 502, 503, 504],
433
errorCodes: ['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN']
434
}),
435
436
// Enhanced error handling
437
interceptors.responseError({
438
throwOnError: process.env.HTTP_THROW_ON_ERROR === 'true',
439
statusCodes: [400, 401, 403, 404, 500, 502, 503, 504],
440
includeResponseBody: true,
441
maxResponseBodySize: 1024
442
})
443
);
444
445
// Set global configuration
446
setGlobalDispatcher(configuredAgent);
447
448
if (process.env.API_BASE_URL) {
449
setGlobalOrigin(process.env.API_BASE_URL);
450
}
451
452
console.log('Advanced undici configuration applied');
453
}
454
455
// Initialize during application startup
456
advancedUndiciConfiguration();
457
```
458
459
## Configuration Best Practices
460
461
### 1. Environment Variables
462
463
Use environment variables for configuration:
464
465
```bash
466
# .env file
467
NODE_ENV=production
468
API_BASE_URL=https://api.production.com
469
HTTP_PROXY=http://proxy.company.com:8080
470
HTTP_POOL_SIZE=20
471
HTTP_KEEP_ALIVE_TIMEOUT=120000
472
HTTP_MAX_RETRIES=5
473
```
474
475
### 2. Graceful Shutdown
476
477
Properly close global dispatcher during application shutdown:
478
479
```javascript
480
import { getGlobalDispatcher } from 'undici';
481
482
process.on('SIGTERM', async () => {
483
console.log('Shutting down gracefully...');
484
485
const dispatcher = getGlobalDispatcher();
486
if (dispatcher && typeof dispatcher.close === 'function') {
487
await dispatcher.close();
488
}
489
490
process.exit(0);
491
});
492
```
493
494
### 3. Health Checks
495
496
Monitor global dispatcher health:
497
498
```javascript
499
import { getGlobalDispatcher } from 'undici';
500
501
async function healthCheck() {
502
try {
503
const dispatcher = getGlobalDispatcher();
504
505
// Test with a lightweight request
506
const response = await fetch('/health', {
507
method: 'HEAD',
508
dispatcher // Use specific dispatcher for health check
509
});
510
511
return response.ok;
512
} catch (error) {
513
console.error('Health check failed:', error.message);
514
return false;
515
}
516
}
517
518
// Run health checks periodically
519
setInterval(async () => {
520
const isHealthy = await healthCheck();
521
console.log(`HTTP client health: ${isHealthy ? 'OK' : 'FAIL'}`);
522
}, 30000);
523
```