Built-in HTTP client with application integration, context awareness, request/response logging, and comprehensive configuration options for making external API calls.
Enhanced HTTP client that extends urllib's HttpClient with Egg.js application integration and configuration management.
/**
* Enhanced HTTP client with app integration extending urllib HttpClient
* @param app - Application instance for configuration and logging
* @param options - HTTP client configuration options
*/
class HttpClient extends RawHttpClient {
constructor(app: EggApplicationCore, options?: HttpClientOptions);
/**
* Make HTTP request with application context
* @param url - Request URL (string, URL object, or RequestURLObject)
* @param options - Request options including method, data, headers, etc.
* @returns Promise resolving to HTTP response
*/
request<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
/**
* Alias for request method (curl-style API)
* @param url - Request URL
* @param options - Request options
* @returns Promise resolving to HTTP response
*/
curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
}Usage Examples:
import { HttpClient } from 'egg';
// Create HTTP client in application startup
const httpClient = new HttpClient(app, {
defaultArgs: {
timeout: 5000,
headers: {
'User-Agent': 'MyApp/1.0.0'
}
}
});
// Make GET request
const response = await httpClient.request('https://api.example.com/users', {
method: 'GET',
dataType: 'json'
});
// Make POST request
const createResponse = await httpClient.curl('https://api.example.com/users', {
method: 'POST',
data: {
name: 'John Doe',
email: 'john@example.com'
},
dataType: 'json',
contentType: 'json'
});
console.log('Created user:', createResponse.data);Context-aware HTTP client wrapper that automatically includes context information in requests.
/**
* Context-aware HTTP client wrapper
* @param ctx - Request context for automatic context integration
*/
class ContextHttpClient {
/** Request context */
ctx: Context;
/** Application instance */
app: EggApplicationCore;
constructor(ctx: Context);
/**
* Make HTTP request with context information
* @param url - Request URL
* @param options - Request options (ctx will be automatically added)
* @returns Promise resolving to HTTP response
*/
curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
/**
* Alias for curl method
* @param url - Request URL
* @param options - Request options
* @returns Promise resolving to HTTP response
*/
request<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
}Usage Examples:
// In controller or service
export default class ApiController extends Controller {
async fetchUserData() {
const { ctx } = this;
// Context HTTP client automatically includes request context
const response = await ctx.httpclient.curl('https://api.example.com/user/profile', {
method: 'GET',
headers: {
'Authorization': `Bearer ${ctx.get('authorization')}`
},
dataType: 'json'
});
// Request is automatically logged with context information
this.logger.info('Fetched user data: %s', response.data.id);
ctx.body = response.data;
}
async updateUserProfile() {
const { ctx } = this;
const updateData = ctx.request.body;
try {
// Use request alias
const response = await ctx.httpClient.request('https://api.example.com/user/profile', {
method: 'PUT',
data: updateData,
contentType: 'json',
dataType: 'json',
timeout: 10000
});
ctx.body = {
success: true,
data: response.data
};
} catch (error) {
this.logger.error('Profile update failed:', error);
ctx.throw(500, 'Profile update failed');
}
}
}Access HTTP client at application level for background tasks and non-request operations.
/**
* Application-level HTTP client access
*/
interface EggApplicationCore {
/** Get application HTTP client instance */
get httpClient(): HttpClient;
/** Create new HTTP client with custom options */
createHttpClient(options?: HttpClientOptions): HttpClient;
/** Make HTTP request using app's default client */
curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
}Usage Examples:
// In application startup or agent
export default class AppBootHook {
async didReady() {
const { app } = this;
// Use application HTTP client
const healthCheck = await app.curl('https://api-health.example.com/status', {
method: 'GET',
dataType: 'json',
timeout: 3000
});
app.logger.info('External API health: %s', healthCheck.data.status);
// Create custom HTTP client for specific API
const apiClient = app.createHttpClient({
defaultArgs: {
headers: {
'X-API-Key': app.config.externalApi.key,
'Content-Type': 'application/json'
},
timeout: 15000
}
});
// Store for later use
app.apiClient = apiClient;
}
}
// In background task
export default class DataSyncSubscription extends Subscription {
async subscribe() {
const { app } = this;
// Use custom API client
const syncData = await app.apiClient.request('https://api.example.com/sync', {
method: 'POST',
data: { lastSync: app.config.lastSyncTime },
dataType: 'json'
});
this.logger.info('Synced %d records', syncData.data.count);
}
}Configuration options for customizing HTTP client behavior.
interface HttpClientOptions {
/** Default request arguments applied to all requests */
defaultArgs?: HttpClientRequestOptions;
/** Additional options from urllib ClientOptions */
[key: string]: any;
}
interface HttpClientRequestOptions extends RequestOptions {
/** Request context (automatically set by ContextHttpClient) */
ctx?: Context;
/** Tracer for request tracking */
tracer?: any;
/** Request method */
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
/** Request data (body) */
data?: any;
/** Response data type parsing */
dataType?: 'json' | 'text' | 'stream';
/** Request content type */
contentType?: 'json' | 'form' | 'stream' | string;
/** Request headers */
headers?: Record<string, string>;
/** Request timeout in milliseconds */
timeout?: number;
/** Follow redirects */
followRedirect?: boolean;
/** Maximum redirects to follow */
maxRedirects?: number;
/** Enable gzip compression */
gzip?: boolean;
/** HTTP Basic auth */
auth?: string;
/** Custom user agent */
agent?: string;
}
interface HttpClientConfig {
/** Default timeout for all requests */
timeout?: number;
/** Default request options */
request?: HttpClientRequestOptions;
/** Enable HTTP/2 support */
allowH2?: boolean;
}Usage Examples:
// In config/config.default.js
export const httpclient: HttpClientConfig = {
timeout: 60000, // 60 seconds default timeout
request: {
headers: {
'User-Agent': 'MyEggApp/1.0.0'
}
},
allowH2: true
};
// Custom client with specific configuration
const apiClient = app.createHttpClient({
defaultArgs: {
timeout: 30000,
headers: {
'Accept': 'application/json',
'X-Client-Version': '2.0'
},
gzip: true,
followRedirect: true,
maxRedirects: 3
}
});
// Request with custom options
const response = await apiClient.request('https://api.example.com/data', {
method: 'POST',
data: requestData,
contentType: 'json',
dataType: 'json',
timeout: 45000, // Override default
headers: {
'X-Request-ID': generateRequestId()
}
});type HttpClientRequestURL = string | URL | RequestURLObject;
interface RequestURLObject {
protocol?: string;
hostname?: string;
port?: number;
pathname?: string;
search?: string;
hash?: string;
}
interface HttpClientResponse<T = any> {
/** HTTP status code */
status: number;
/** Response headers */
headers: Record<string, string | string[]>;
/** Parsed response data */
data: T;
/** Raw response object */
res: IncomingMessage;
/** Response time in milliseconds */
rt?: number;
/** Request size in bytes */
size?: number;
/** Response timing information */
timing?: RequestTiming;
}
interface RequestTiming {
/** DNS lookup time */
dnslookup: number;
/** TCP connection time */
connected: number;
/** Time to first byte */
requestSent: number;
/** Total request time */
waiting: number;
/** Content download time */
contentDownload: number;
}