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.
HttpClientInterface.Http facade (via adapters like php-http/guzzle7-adapter) or third-party clients (e.g., Guzzle, Symfony HttpClient).Http:: facade—requires refactoring to adopt interface-based design. Ideal for new services, SDKs, or microservices where client interchangeability is critical.symfony/http-client) or planning to migrate from Guzzle to Symfony’s client.HttpClientInterface to a concrete client (e.g., symfony/http-client or Guzzle with PSR-18 bridge).Http::get() calls with injected HttpClientInterface in services.HttpClientInterface is straightforward but requires setup (e.g., MockHttpClient or TestHttpClient).symfony/http-client-contracts (interfaces only).symfony/http-client (recommended) or guzzlehttp/guzzle + guzzlehttp/psr7.php-http/discovery for auto-wiring or symfony/cache for response caching.AsyncHttpClient (not enabled by default).HttpClient (not the contracts layer).throw: false or getStatusCode() checks are needed.symfony/psr-http-message-bridge).symfony/http-client (feature-rich, async) or Guzzle (lightweight, familiar)?Http:: facade be deprecated in favor of HttpClientInterface, or retained as a wrapper?MockHttpClient, TestHttpClient, or custom stubs)?Http:: calls to interface-based services?psr/http-client) or stick to Symfony’s contracts for broader Symfony ecosystem compatibility?symfony/http-client for full feature parity or Guzzle for simplicity.symfony/psr-http-message-bridge to unify PSR-7/18 message types and may need facade adapters.MockHttpClient or Pest via TestHttpClient.Phase 1: Interface Adoption (Low Risk)
symfony/http-client-contracts and a concrete client (e.g., symfony/http-client).HttpClientInterface to the concrete client:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->bind(
HttpClientInterface::class,
fn() => new \Symfony\Component\HttpClient\HttpClient()
);
}
HttpClientInterface in constructors.Phase 2: Facade Deprecation (Medium Risk)
Http::get() calls with injected HttpClientInterface in critical paths (e.g., API clients, background jobs).// app/Facades/HttpClient.php
public static function request(string $method, string $url, array $options = []): ResponseInterface
{
return app(HttpClientInterface::class)->request($method, $url, $options);
}
Phase 3: Cross-Cutting Concerns (Optional)
// app/Services/Decorators/LoggingHttpClient.php
class LoggingHttpClient implements HttpClientInterface
{
public function __construct(private HttpClientInterface $client) {}
public function request(string $method, string $url, array $options): ResponseInterface
{
logger()->debug("HTTP {$method} {$url}");
return $this->client->request($method, $url, $options);
}
}
$this->app->bind(HttpClientInterface::class, fn() => new LoggingHttpClient(
new \Symfony\Component\HttpClient\HttpClient()
));
Phase 4: Testing and Validation
Http::fake() with MockHttpClient or TestHttpClient in unit tests.TestHttpClient to assert request/response cycles).guzzlehttp/psr7 and php-http/guzzle7-adapter for PSR-18 compliance.php-http/laravel-adapter to bridge Laravel’s Http facade to HttpClientInterface.php-http/client).| Priority | Task | Dependencies |
|---|---|---|
| 1 | Install contracts + concrete client | None |
| 2 | Bind HttpClientInterface in service container |
symfony/http-client-contracts |
| 3 | Refactor new services to use HttpClientInterface |
Service container binding |
| 4 | Replace Http:: calls in critical paths |
Interface adoption |
| 5 | Implement decorators/middleware | Concrete client in place |
| 6 | Update tests to use MockHttpClient |
Interface adoption |
| 7 | Deprecate Http:: facade (optional) |
Full interface migration |
HttpClientException).HttpClientInterface is straightforward but requires initial setup.until() callbacks).AsyncHttpClient but requires explicit opt-in.symfony/cache or Laravel’s cache for response caching.How can I help you explore Laravel packages today?