HttpClient
Miko's HttpClient provides a fluent API for making HTTP requests using cURL. Supports GET, POST, PUT, PATCH, DELETE methods with authentication, headers, and retry policies.
HttpClient Methods Summary
| Method | Description |
|---|---|
get($url) | Send GET request |
post($url, $data) | Send POST request |
put($url, $data) | Send PUT request |
patch($url, $data) | Send PATCH request |
delete($url) | Send DELETE request |
setBearerToken($token) | Set Bearer authentication |
setBasicAuth($user, $pass) | Set Basic authentication |
setHeader($key, $value) | Set custom header |
setTimeout($seconds) | Set request timeout |
withRetry($times, $delay) | Enable retry on failure |
Basic Usage
use Miko\Core\Http\HttpClient;
// Create client with base URL
$client = HttpClient::create('https://api.example.com');
// GET request
$response = $client->get('/users');
$users = $response->json();
// POST request
$response = $client->post('/users', [
'name' => 'John Doe',
'email' => 'john@example.com'
]);
// Check response
if ($response->ok()) {
$user = $response->json();
echo "Created user: " . $user['id'];
}
HTTP Methods
GET Request
// Simple GET
$response = $client->get('/users');
// GET with query parameters
$response = $client->get('/users?page=1&limit=10');
// GET with query array
$response = $client->get('/users', [
'query' => [
'page' => 1,
'limit' => 10,
'status' => 'active'
]
]);
POST Request
// POST with JSON body
$response = $client->post('/users', [
'name' => 'John Doe',
'email' => 'john@example.com',
'role' => 'admin'
]);
// POST with form data
$response = $client->post('/upload', [
'file' => new CURLFile('/path/to/file.pdf'),
'description' => 'My document'
], ['Content-Type' => 'multipart/form-data']);
PUT Request
// Full update
$response = $client->put('/users/1', [
'name' => 'John Updated',
'email' => 'john.updated@example.com',
'role' => 'user'
]);
PATCH Request
// Partial update
$response = $client->patch('/users/1', [
'name' => 'John Updated'
]);
DELETE Request
// Delete resource
$response = $client->delete('/users/1');
if ($response->status() === 204) {
echo "User deleted successfully";
}
Authentication
Bearer Token (JWT)
$client = HttpClient::create('https://api.example.com');
// Set bearer token
$client->setBearerToken('eyJhbGciOiJIUzI1NiIs...');
// All subsequent requests include Authorization header
$response = $client->get('/protected/resource');
Basic Authentication
$client = HttpClient::create('https://api.example.com');
// Set basic auth
$client->setBasicAuth('username', 'password');
$response = $client->get('/secure/endpoint');
API Key
$client = HttpClient::create('https://api.example.com');
// API key in header
$client->setHeader('X-API-Key', 'your-api-key');
// Or in query string
$response = $client->get('/data?api_key=your-api-key');
Headers & Options
Custom Headers
// Set single header
$client->setHeader('Accept', 'application/json');
$client->setHeader('X-Custom-Header', 'custom-value');
// Set multiple headers
$client->setHeaders([
'Accept' => 'application/json',
'Accept-Language' => 'en-US',
'X-Request-ID' => uniqid()
]);
Timeout
// Set timeout in seconds
$client->setTimeout(30);
// Short timeout for quick APIs
$client->setTimeout(5);
SSL Verification
// Disable SSL verification (development only!)
$client->setVerifySsl(false);
// Enable (default)
$client->setVerifySsl(true);
Response Handling
Response Object
$response = $client->get('/users/1');
// Status code
$status = $response->status(); // 200
// Status checks
$response->ok(); // true (200-299)
$response->isSuccess(); // true (200-299)
$response->isRedirect(); // true (300-399)
$response->isClientError(); // true (400-499)
$response->isServerError(); // true (500-599)
// Body
$body = $response->body(); // Raw string
$json = $response->json(); // Decoded JSON (array)
$object = $response->json(false); // Decoded JSON (object)
// Headers
$headers = $response->headers();
$contentType = $response->header('Content-Type');
Error Handling
$response = $client->get('/users/999');
if (!$response->ok()) {
echo "Error: " . $response->status();
echo "Message: " . $response->json()['error'] ?? 'Unknown error';
}
// Throw exception on error
try {
$response->throwIfFailed();
$user = $response->json();
} catch (HttpException $e) {
echo "Request failed: " . $e->getMessage();
}
Retry Policy
Automatically retry failed requests.
// Retry up to 3 times with 1 second delay
$response = $client->withRetry(3, 1000)->get('/unstable-api');
// Custom retry logic
$response = $client->request('GET', '/api/data', null, [], [
'retries' => 3,
'retry_delay' => 1000, // milliseconds
'retry_on' => [500, 502, 503, 504] // Status codes to retry
]);
Parallel Requests (Async)
Execute multiple requests simultaneously.
// Define requests
$requests = [
['method' => 'GET', 'url' => '/users'],
['method' => 'GET', 'url' => '/products'],
['method' => 'GET', 'url' => '/orders'],
['method' => 'POST', 'url' => '/analytics', 'data' => ['event' => 'page_view']]
];
// Execute in parallel
$responses = $client->multi($requests);
// Process responses
$users = $responses[0]->json();
$products = $responses[1]->json();
$orders = $responses[2]->json();
Practical Examples
REST API Client
class UserApiClient
{
private HttpClient $client;
public function __construct(string $baseUrl, string $apiKey)
{
$this->client = HttpClient::create($baseUrl);
$this->client->setHeader('X-API-Key', $apiKey);
$this->client->setTimeout(30);
}
public function getUsers(int $page = 1, int $limit = 20): array
{
$response = $this->client->get("/users?page={$page}&limit={$limit}");
$response->throwIfFailed();
return $response->json();
}
public function getUser(int $id): ?array
{
$response = $this->client->get("/users/{$id}");
if ($response->status() === 404) {
return null;
}
$response->throwIfFailed();
return $response->json();
}
public function createUser(array $data): array
{
$response = $this->client->post('/users', $data);
$response->throwIfFailed();
return $response->json();
}
public function updateUser(int $id, array $data): array
{
$response = $this->client->put("/users/{$id}", $data);
$response->throwIfFailed();
return $response->json();
}
public function deleteUser(int $id): bool
{
$response = $this->client->delete("/users/{$id}");
return $response->status() === 204;
}
}
// Usage
$api = new UserApiClient('https://api.example.com', 'your-api-key');
$users = $api->getUsers(1, 10);
$user = $api->createUser(['name' => 'John', 'email' => 'john@example.com']);
$api->updateUser($user['id'], ['name' => 'John Updated']);
$api->deleteUser($user['id']);
OAuth2 Token Refresh
class OAuth2Client
{
private HttpClient $client;
private string $accessToken;
private string $refreshToken;
private int $expiresAt;
public function __construct(string $baseUrl)
{
$this->client = HttpClient::create($baseUrl);
}
public function authenticate(string $clientId, string $clientSecret): void
{
$response = $this->client->post('/oauth/token', [
'grant_type' => 'client_credentials',
'client_id' => $clientId,
'client_secret' => $clientSecret
]);
$response->throwIfFailed();
$data = $response->json();
$this->accessToken = $data['access_token'];
$this->refreshToken = $data['refresh_token'] ?? null;
$this->expiresAt = time() + $data['expires_in'];
}
public function request(string $method, string $url, ?array $data = null): array
{
// Refresh token if expired
if (time() >= $this->expiresAt - 60) {
$this->refreshAccessToken();
}
$this->client->setBearerToken($this->accessToken);
$response = match($method) {
'GET' => $this->client->get($url),
'POST' => $this->client->post($url, $data),
'PUT' => $this->client->put($url, $data),
'DELETE' => $this->client->delete($url),
};
$response->throwIfFailed();
return $response->json();
}
private function refreshAccessToken(): void
{
$response = $this->client->post('/oauth/token', [
'grant_type' => 'refresh_token',
'refresh_token' => $this->refreshToken
]);
$response->throwIfFailed();
$data = $response->json();
$this->accessToken = $data['access_token'];
$this->expiresAt = time() + $data['expires_in'];
}
}
Webhook Sender
class WebhookSender
{
private HttpClient $client;
public function __construct()
{
$this->client = HttpClient::create('');
$this->client->setTimeout(10);
$this->client->setHeader('Content-Type', 'application/json');
}
public function send(string $url, string $event, array $payload): bool
{
$data = [
'event' => $event,
'timestamp' => date('c'),
'payload' => $payload
];
// Sign the payload
$signature = hash_hmac('sha256', json_encode($data), $_ENV['WEBHOOK_SECRET']);
$this->client->setHeader('X-Webhook-Signature', $signature);
try {
$response = $this->client->withRetry(3, 1000)->post($url, $data);
return $response->ok();
} catch (Exception $e) {
Logger::error("Webhook failed: " . $e->getMessage());
return false;
}
}
}
// Usage
$webhook = new WebhookSender();
$webhook->send('https://example.com/webhook', 'order.created', [
'order_id' => 123,
'total' => 99.99
]);