or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application.mdbase-classes.mdconfiguration.mdcontext.mdhttp-client.mdindex.mdloaders-errors.mdstartup.md
tile.json

http-client.mddocs/

HTTP Client

Built-in HTTP client with application integration, context awareness, request/response logging, and comprehensive configuration options for making external API calls.

Capabilities

HttpClient Class

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);

ContextHttpClient Class

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');
    }
  }
}

Application-Level HTTP Client

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);
  }
}

HTTP Client Configuration

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()
  }
});

Types

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;
}