symfony/http-client-contracts
Symfony HttpClient Contracts provides stable interfaces for HTTP clients and responses, extracted from Symfony. Build libraries against these battle-tested abstractions and swap implementations easily while staying compatible with Symfony’s HttpClient ecosystem.
Install via Composer:
composer require symfony/http-client-contracts
This package supplies only interfaces — no implementations. You must pair it with a concrete HTTP client:
symfony/http-client (recommended for Symfony projects — supports HTTP/2, async, pooling)guzzlehttp/guzzle (via guzzlehttp/psr7)php-http/discovery (auto-discovers installed client)First use: inject Symfony\Contracts\HttpClient\HttpClientInterface into a service and type-hint against the interface:
use Symfony\Contracts\HttpClient\HttpClientInterface;
class WeatherClient
{
public function __construct(private HttpClientInterface $client) {}
public function getForecast(string $city): array
{
$response = $this->client->request('GET', 'https://api.openweathermap.org/data/2.5/weather', [
'query' => ['q' => $city, 'appid' => $_ENV['OWM_API_KEY']],
]);
return $response->toArray(false); // avoid JSON decode error on empty body
}
}
✅ Key first step: Use HttpClientInterface in constructors, not the concrete HttpClient class.
HttpClientInterface — never concrete clients. Enables swapping (e.g., production → test client with MockHttpClient).HttpClientInterface alias in config/services.yaml:
Symfony\Contracts\HttpClient\HttpClientInterface: '@Symfony\Component\HttpClient\HttpClient'
HttpClientInterface and return MockResponse::fromJsonString() stubs.TestHttpClient (via symfony/http-client’s testing tools) to assert request counts/URLs.psr/http-client and psr/http-message interfaces where possible (Symfony’s contracts implement PSR-18 equivalents). Supports interoperability with Laravel’s http client or Laravel Http Client via adapters.class LoggingHttpClient implements HttpClientInterface
{
public function request(string $method, string $url, array $options = []): ResponseInterface
{
logger()->info('HTTP request', ['method' => $method, 'url' => $url]);
return $this->client->request($method, $url, $options);
}
}
HttpClientInterface alone won’t resolve. Ensure symfony/http-client is installed or another PSR-18 implementation.toArray(), getContent(), getHeaders() throw on invalid status (e.g., 4xx/5xx). Use ResponseInterface->getStatusCode() before content extraction, or enable throw option:
$response = $client->request('GET', $url, ['throw' => true]); // throws HttpClientException on non-2xx
ResponseInterface::until() and cancel(), but basic request() calls are synchronous unless using AsyncHttpClient (from symfony/http-client) or PSR-18 async clients.symfony/http-client:
# config/packages/http_client.yaml
framework:
http_client:
max_host_connections: 5
scoped_clients:
weather_api:
base_uri: 'https://api.openweathermap.org'
headers: { Authorization: '%env(OWM_API_KEY)%' }
HttpClientInterface in middleware/decorators for auth, caching (cache.php-cache), or retry logic (symfony/http-client-contract-compatible retry strategies).symfony/psr-http-message-bridge to unify PSR-7/18 and Symfony message types.How can I help you explore Laravel packages today?