187 lines
4.7 KiB
Markdown
187 lines
4.7 KiB
Markdown
# @stock-bot/http-client
|
|
|
|
High-performance HTTP client for Stock Bot microservices built on Bun's native fetch API.
|
|
|
|
## Features
|
|
|
|
- **Ultra-fast performance** - Built on Bun's native fetch implementation
|
|
- **Connection pooling** - Efficiently manages connections to prevent overwhelming servers
|
|
- **Automatic retries** - Handles transient network errors with configurable retry strategies
|
|
- **Timeout management** - Prevents requests from hanging indefinitely
|
|
- **Streaming support** - Efficient handling of large responses
|
|
- **TypeScript support** - Full type safety for all operations
|
|
- **Metrics & monitoring** - Built-in performance statistics
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
bun add @stock-bot/http-client
|
|
```
|
|
|
|
## Basic Usage
|
|
|
|
```typescript
|
|
import { BunHttpClient } from '@stock-bot/http-client';
|
|
|
|
// Create a client
|
|
const client = new BunHttpClient({
|
|
baseURL: 'https://api.example.com',
|
|
timeout: 5000,
|
|
retries: 3
|
|
});
|
|
|
|
// Make requests
|
|
async function fetchData() {
|
|
try {
|
|
// GET request
|
|
const response = await client.get('/users');
|
|
console.log(response.data);
|
|
|
|
// POST request with data
|
|
const createResponse = await client.post('/users', {
|
|
name: 'John Doe',
|
|
email: 'john@example.com'
|
|
});
|
|
console.log(createResponse.data);
|
|
} catch (error) {
|
|
console.error('Request failed:', error.message);
|
|
}
|
|
}
|
|
|
|
// Close when done
|
|
await client.close();
|
|
```
|
|
|
|
## Advanced Configuration
|
|
|
|
```typescript
|
|
const client = new BunHttpClient({
|
|
baseURL: 'https://api.example.com',
|
|
timeout: 10000,
|
|
retries: 3,
|
|
retryDelay: 1000,
|
|
maxConcurrency: 20,
|
|
keepAlive: true,
|
|
headers: {
|
|
'User-Agent': 'StockBot/1.0',
|
|
'Authorization': 'Bearer token'
|
|
},
|
|
validateStatus: (status) => status >= 200 && status < 300
|
|
});
|
|
```
|
|
|
|
## Connection Pooling
|
|
|
|
The HTTP client automatically manages connection pooling with smart limits:
|
|
|
|
```typescript
|
|
// Get connection statistics
|
|
const stats = client.getStats();
|
|
console.log(`Active connections: ${stats.activeConnections}`);
|
|
console.log(`Success rate: ${stats.successfulRequests / (stats.successfulRequests + stats.failedRequests)}`);
|
|
console.log(`Average response time: ${stats.averageResponseTime}ms`);
|
|
|
|
// Health check
|
|
const health = await client.healthCheck();
|
|
if (health.healthy) {
|
|
console.log('HTTP client is healthy');
|
|
} else {
|
|
console.log('HTTP client is degraded:', health.details);
|
|
}
|
|
```
|
|
|
|
## Event Handling
|
|
|
|
```typescript
|
|
// Listen for specific events
|
|
client.on('response', ({ host, response }) => {
|
|
console.log(`Response from ${host}: ${response.status}`);
|
|
});
|
|
|
|
client.on('error', ({ host, error }) => {
|
|
console.log(`Error from ${host}: ${error.message}`);
|
|
});
|
|
|
|
client.on('retryAttempt', (data) => {
|
|
console.log(`Retrying request (${data.attempt}/${data.config.retries}): ${data.error.message}`);
|
|
});
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### BunHttpClient
|
|
|
|
Main HTTP client class with connection pooling and retry support.
|
|
|
|
#### Methods
|
|
|
|
- `request(config)`: Make a request with full configuration options
|
|
- `get(url, config?)`: Make a GET request
|
|
- `post(url, data?, config?)`: Make a POST request with data
|
|
- `put(url, data?, config?)`: Make a PUT request with data
|
|
- `patch(url, data?, config?)`: Make a PATCH request with data
|
|
- `delete(url, config?)`: Make a DELETE request
|
|
- `head(url, config?)`: Make a HEAD request
|
|
- `options(url, config?)`: Make an OPTIONS request
|
|
- `getStats()`: Get connection statistics
|
|
- `healthCheck()`: Check health of the client
|
|
- `close()`: Close all connections
|
|
- `setBaseURL(url)`: Update the base URL
|
|
- `setDefaultHeaders(headers)`: Update default headers
|
|
- `setTimeout(timeout)`: Update default timeout
|
|
- `create(config)`: Create a new instance with different config
|
|
|
|
### Request Configuration
|
|
|
|
```typescript
|
|
interface RequestConfig {
|
|
url: string;
|
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
|
|
headers?: Record<string, string>;
|
|
body?: any;
|
|
timeout?: number;
|
|
retries?: number;
|
|
validateStatus?: (status: number) => boolean;
|
|
metadata?: Record<string, any>;
|
|
}
|
|
```
|
|
|
|
### Response Object
|
|
|
|
```typescript
|
|
interface HttpResponse<T = any> {
|
|
data: T;
|
|
status: number;
|
|
statusText: string;
|
|
headers: Record<string, string>;
|
|
config: RequestConfig;
|
|
timing: {
|
|
start: number;
|
|
end: number;
|
|
duration: number;
|
|
};
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```typescript
|
|
try {
|
|
const response = await client.get('/resource-that-might-fail');
|
|
processData(response.data);
|
|
} catch (error) {
|
|
if (error instanceof TimeoutError) {
|
|
console.log('Request timed out');
|
|
} else if (error instanceof RetryExhaustedError) {
|
|
console.log(`Request failed after ${error.config.retries} retries`);
|
|
} else if (error instanceof HttpClientError) {
|
|
console.log(`HTTP error: ${error.status} - ${error.message}`);
|
|
} else {
|
|
console.log('Unexpected error', error);
|
|
}
|
|
}
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|