boson-php/http
Lightweight HTTP client utilities for PHP. Provides simple request/response handling with a focus on clear, minimal APIs suitable for small services, scripts, and internal tools. Designed to keep dependencies low while staying easy to extend and integrate.
Installation
composer require boson-php/http
Add to composer.json if not auto-loaded:
"autoload": {
"psr-4": {
"App\\": "app/",
"Boson\\Http\\": "vendor/boson-php/http/src/"
}
}
Run composer dump-autoload.
First Use Case: HTTP Client Initialize a client with a base URL:
use Boson\Http\Client;
$client = new Client('https://api.example.com/v1');
Quick Request
$response = $client->get('/users');
$data = $response->json(); // Decode JSON response
Key Classes to Know
Boson\Http\Client: Core HTTP client.Boson\Http\Response: Handles responses (status, body, headers).Boson\Http\Request: Builds requests (methods, headers, body).Request Building Chain methods for clarity:
$response = $client
->withHeader('Authorization', 'Bearer token')
->post('/users', ['name' => 'John'])
->withJson();
Middleware Integration Attach middleware to the client:
$client->pushMiddleware(function ($request) {
$request->withHeader('X-Custom-Header', 'value');
return $request;
});
Async Requests (if supported)
$promise = $client->asyncGet('/users');
$promise->then(function ($response) {
// Handle response
});
Retry Logic Implement retry middleware:
$client->pushMiddleware(function ($request, $next) {
$attempts = 0;
while ($attempts < 3) {
try {
return $next($request);
} catch (Exception $e) {
$attempts++;
if ($attempts === 3) throw $e;
sleep(1);
}
}
});
Laravel Service Provider Bind the client to the container:
$this->app->singleton(Client::class, function ($app) {
return new Client(config('services.api.base_url'));
});
Dependency Injection
Inject Client into controllers/services:
public function __construct(private Client $client) {}
Configuration
Use Laravel config (e.g., config/services.php):
'api' => [
'base_url' => env('API_BASE_URL'),
'timeout' => 30,
],
Then initialize:
$client = new Client(config('services.api.base_url'));
$client->setTimeout(config('services.api.timeout'));
No Built-in Retry Retry logic must be manually implemented via middleware (see Implementation Patterns).
Limited Error Handling Custom exceptions may need wrapping:
try {
$response = $client->get('/users');
} catch (Exception $e) {
throw new \RuntimeException("API Error: {$e->getMessage()}", 0, $e);
}
No Automatic JSON Parsing
Use $response->json() explicitly; raw responses require $response->getBody().
No Built-in Rate Limiting Implement middleware for rate limiting:
$client->pushMiddleware(function ($request, $next) {
static $lastRequestTime = 0;
$interval = 1; // seconds
if (time() - $lastRequestTime < $interval) {
usleep(($interval - (time() - $lastRequestTime)) * 1000000);
}
$lastRequestTime = time();
return $next($request);
});
Log Requests/Responses Add middleware for debugging:
$client->pushMiddleware(function ($request, $next) {
\Log::debug('Request:', [
'url' => $request->getUri(),
'method' => $request->getMethod(),
'headers' => $request->getHeaders(),
'body' => $request->getBody(),
]);
$response = $next($request);
\Log::debug('Response:', [
'status' => $response->getStatusCode(),
'body' => $response->getBody(),
]);
return $response;
});
Check Headers
Ensure Content-Type: application/json is set for JSON requests:
$client->withHeader('Content-Type', 'application/json');
Custom Request Factories
Extend Boson\Http\Request to add domain-specific logic:
class CustomRequest extends Request {
public function withAuthToken(string $token): self {
return $this->withHeader('Authorization', "Bearer {$token}");
}
}
Response Decorators Create a decorator for domain-specific responses:
class UserResponse {
public function __construct(private Response $response) {}
public function getUsers(): array {
return $this->response->json()['data'] ?? [];
}
}
Plugin System Use traits or interfaces to add functionality:
trait Retryable {
public function retry(int $maxAttempts = 3): Response {
// Implement retry logic
}
}
Default Timeout Set globally via constructor or middleware:
$client = new Client('https://api.example.com', [
'timeout' => 30,
]);
SSL Verification Disable only for testing (not production):
$client->setVerifyPeer(false); // Not recommended for prod!
How can I help you explore Laravel packages today?