ncbp / http-client
HTTP interfaces, client, and supporting classes
Requires
- php: >=8.2
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- psr/log: ^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpunit/phpunit: ^11.5
This package is not auto-updated.
Last update: 2025-06-05 18:39:06 UTC
README
A robust, PSR-compliant HTTP client library with built-in retry mechanisms for reliable API communication.
Features
- PSR Compliance: Follows PSR-7 (HTTP Message), PSR-18 (HTTP Client), PSR-17 (HTTP Factories), and PSR-3 (Logging) standards
- Intelligent Retry Mechanism: Automatically retries failed requests with exponential backoff and jitter
- Comprehensive Error Handling: Distinguishes between transient and permanent errors
- Detailed Logging: Extensive logging for debugging and monitoring
- Clean API: Simple, intuitive interface for all standard HTTP methods
Requirements
- PHP 8.2 or higher
- PSR-18 compatible HTTP client
- PSR-17 compatible request factory
- PSR-3 compatible logger
Installation
Install via Composer:
composer require ncbp/http-client
Basic Usage
// Create the client
$httpClient = new \NCBP\HttpClient\HttpClient(
$psrHttpClient, // PSR-18 HTTP client implementation
$requestFactory, // PSR-17 request factory implementation
$logger, // PSR-3 logger implementation
$maxAttempts = 3, // Optional: default is 3
$baseDelayMs = 100 // Optional: default is 100ms
);
// Make requests
try {
// GET request
$response = $httpClient->get('https://api.example.com/users', [
'headers' => [
'Authorization' => 'Bearer token123',
'Accept' => 'application/json',
],
'query' => [
'page' => 1,
'limit' => 10,
],
]);
// POST request with JSON body
$stream = $streamFactory->createStream(json_encode([
'name' => 'John Doe',
'email' => 'john@example.com',
]));
$response = $httpClient->post('https://api.example.com/users', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer token123',
],
'body' => $stream,
]);
// Process the response
$statusCode = $response->getStatusCode();
$body = (string) $response->getBody();
$data = json_decode($body, true);
} catch (\NCBP\HttpClient\Exception\HttpRequestException $e) {
// Handle client errors (4xx)
$request = $e->getRequest();
$response = $e->getResponse();
// Log or handle the error
} catch (\NCBP\HttpClient\Exception\HttpResponseException $e) {
// Handle server errors (5xx) after all retry attempts failed
// Log or handle the error
} catch (\NCBP\HttpClient\Exception\HttpException $e) {
// Handle other HTTP-related errors
// Log or handle the error
}
Available Methods
get(string $path, array $options = []): ResponseInterface
post(string $path, array $options = []): ResponseInterface
put(string $path, array $options = []): ResponseInterface
patch(string $path, array $options = []): ResponseInterface
delete(string $path, array $options = []): ResponseInterface
Request Options
The $options
array supports the following keys:
headers
: Associative array of request headersquery
: Associative array of query parametersbody
: PSR-7 StreamInterface containing the request body (for POST, PUT, PATCH)
Retry Mechanism
The client automatically retries requests that fail with server errors (5xx status codes) using an exponential backoff strategy with random jitter:
- First retry: Base delay × 2¹ + random jitter
- Second retry: Base delay × 2² + random jitter
- And so on...
This approach helps prevent overwhelming the server during outages and avoids the "thundering herd" problem when services recover.
Configuration
You can configure the retry behavior when instantiating the client:
$httpClient = new \NCBP\HttpClient\HttpClient(
$psrHttpClient,
$requestFactory,
$logger,
$maxAttempts = 5, // Maximum number of attempts (default: 3)
$baseDelayMs = 200 // Base delay in milliseconds (default: 100)
);
Exception Hierarchy
HttpException
: Base exception class for all HTTP-related errorsHttpRequestException
: Thrown for client errors (4xx status codes)HttpResponseException
: Thrown when all retry attempts fail
All exceptions provide access to the original request and response objects:
try {
$response = $httpClient->get('https://api.example.com/resource');
} catch (\NCBP\HttpClient\Exception\HttpException $e) {
$request = $e->getRequest(); // PSR-7 RequestInterface
$response = $e->getResponse(); // PSR-7 ResponseInterface (may be null)
}
Testing and Code Coverage
This library maintains 100% code coverage to ensure reliability and stability.
License
MIT License