symfony/http-client
Symfony HttpClient provides a modern HTTP client for PHP with sync and async requests, streaming responses, retries, and built-in support for common auth and options. Designed for performance, flexible transports, and smooth integration with Symfony apps.
HttpClient is a battle-tested, feature-rich HTTP client that aligns seamlessly with Laravel’s dependency injection (via Symfony’s HttpClient integration in Laravel 10+) and service container. It replaces Laravel’s native Http facade (Guzzle-based) while offering superior performance, async support, and middleware extensibility.CachingHttpClient, NoPrivateNetworkHttpClient), enabling TPMs to compose clients with retries, caching, auth, and observability without vendor lock-in. This fits Laravel’s modular architecture (e.g., middleware, service providers).AsyncResponse) align with Laravel’s growing adoption of async/await (e.g., queues, Horizon). Ideal for high-throughput APIs or background jobs.CachingHttpClient integrates with PSR-6 caches (e.g., Laravel’s cache()), reducing external API calls—a critical feature for cost-sensitive or latency-prone systems.HttpClient is the default in Laravel 10, with a symfony/http-client facade (HttpClient::create()). Existing Guzzle-based code can be incrementally replaced.Http facade remains a wrapper around Guzzle, but new projects should prioritize symfony/http-client for long-term maintainability.AddQueuedCookiesMiddleware) can be adapted to Symfony’s decorators, though some refactoring may be needed for custom logic.HttpClient has a steeper API than Guzzle (e.g., Response objects differ, async workflows require AsyncResponse). TPMs must upskill engineers on:
wait() vs. then()).symfony/event-dispatcher). Tree-shaking via Composer’s replace or Laravel Mix can mitigate this.CachingHttpClient requires PSR-6 cache integration, adding complexity to cache invalidation strategies (e.g., TTL management, stale-while-revalidate).GuzzleHttp\Promise), migration may require refactoring.AsyncResponse) integrate with Laravel’s sync-first workflows (e.g., controllers, commands)?CachingHttpClient’s freshness_lifetime).CurlHttpClient?max_host_connections) be tuned for high-load scenarios?HttpClient with Laravel’s logging/monitoring (e.g., tap() for response debugging)?HttpClient introduces regressions (e.g., CVE-2026-48736 IPv6 issues)?symfony/http-client facade. Replace Http::get() with HttpClient::create()->request().symfony/http-client as a standalone package (via Composer) and wrap it in a service provider for consistency.AsyncResponse). Ensure the app’s phpversion constraint is updated.PsrHttpMessage, Cache) for cohesion. Example:
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Component\HttpClient\CachingHttpClient;
$cache = app(CacheInterface::class);
$client = new CachingHttpClient(
HttpClient::create(),
$cache,
new CacheItemFactory()
);
symfony/http-client.RetryHttpClient, CachingHttpClient).// Before (Guzzle)
$response = Http::withOptions(['timeout' => 10])->get('https://api.example.com');
// After (Symfony)
$client = HttpClient::create(['timeout' => 10]);
$response = $client->request('GET', 'https://api.example.com');
$response = $client->request('GET', 'https://api.example.com');
$response->then(function (ResponseInterface $res) {
// Handle async response in a job
});
Http facade globally using a service provider:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton('http.client', fn() => HttpClient::create());
}
resolve(HttpClientInterface::class)).| Guzzle Feature | Symfony Equivalent |
|---|---|
Http::withOptions() |
HttpClient::create(['options' => [...]]) |
GuzzleHttp\Promise |
AsyncResponse + wait()/then() |
| Middleware | Decorators (e.g., RetryHttpClient) |
| Streamed Responses | ResponseInterface::getContent() (streaming) |
Http::macro() with custom decorators.symfony/http-client's tap() for middleware-like behavior:
$client->request('GET', '...')->tap(function (Response $res) {
// Modify response (e.g., add headers)
});
$response = HttpClient::create()->request('GET', '/');
expect($response->getStatusCode())->toBe(200);
expect($response->then(...)).CachingHttpClient requires proactive TTL management to avoid stale data.HttpClient API (e.g., async patterns, decorator composition).CurlHttpClient state sharing, async timeouts).HttpClient is PSR-compliant and interoperable with other HTTP libraries.How can I help you explore Laravel packages today?