HTTP client
The outgoing client lets a Raxos application call other services. It wraps a configured Guzzle client behind a small fluent builder and a convenient response wrapper.
Creating a client
HttpClient takes an optional base URL and a default timeout. Under the hood it configures a Guzzle client with http_errors disabled, so non-2xx responses come back as normal responses rather than exceptions:
<?php
declare(strict_types=1);
use Raxos\Http\Client\HttpClient;
$client = new HttpClient(baseUrl: 'https://api.example.com', timeout: 5.0);The client forwards any unknown method call to a fresh HttpClientRequest through __call(), which is why the fluent builder methods below can be called directly on the client.
Building a request
HttpClientRequest exposes a fluent builder. Each method returns the request, so calls chain, and the terminal verb performs the request:
$response = $client
->bearerToken('secret-token')
->header('Accept', 'application/json')
->query(['active' => 1])
->get('/users');The available builder methods are:
header(string $name, string $value, bool $replace = true)basicAuth(string $username, string $password)digestAuth(string $username, string $password)bearerToken(string $token)query(array $query)json(array $json)multipart(array $data)options(array $options)timeout(float $timeout)
The terminal verbs are get(string $uri, ?array $query = null), post(string $uri, ?array $json = null) and delete(string $uri). The get() and post() shortcuts accept the query or JSON body inline:
$response = $client->post('/users', json: [
'name' => 'Bas',
'email' => 'bas@mili.us'
]);Reading the response
HttpClientResponse wraps the underlying PSR-7 response. It exposes the parsed protocolVersion, responseCode (an HttpResponseCode) and responseText as public properties, plus accessor methods:
if ($response->success()) {
$users = $response->json();
} elseif ($response->clientError()) {
// 4xx
} elseif ($response->serverError()) {
// 5xx
}The body accessors are body() for the raw string, json(bool $associative = true) for parsed JSON and stream() for the PSR-7 stream. Header access is header(string $name, bool $single = true), headers(bool $single = true) and hasHeader(string $name). The status helpers are success(), failed(), clientError() and serverError().
Errors
Guzzle transport failures are translated into a RequestFailedException, which implements Raxos\Contract\Http\HttpClientExceptionInterface. Because http_errors is disabled, a 4xx or 5xx response does not throw; only a transport level failure (a timeout or a DNS error, for example) does.
<?php
declare(strict_types=1);
use Raxos\Contract\Http\HttpClientExceptionInterface;
use Raxos\Http\Client\HttpClient;
$client = new HttpClient();
try {
$response = $client->get('https://api.example.com/health');
} catch (HttpClientExceptionInterface $err) {
// transport failure
}PSR-18 and PSR-17 bridge
For interoperability with libraries that expect PSR interfaces, Raxos\Http\Client\Psr\Psr18Client adapts HttpClient to the PSR-18 ClientInterface, and HttpFactory implements the PSR-17 request, response, server request, stream, uploaded file and URI factories. Use them when a third party library asks for a PSR client or factory instead of the Raxos client.