Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Http Client Contracts Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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.

Implementation Patterns

  • Interface-first design: All external HTTP dependencies should accept HttpClientInterface — never concrete clients. Enables swapping (e.g., production → test client with MockHttpClient).
  • Symfony dependency injection: Register HttpClientInterface alias in config/services.yaml:
    Symfony\Contracts\HttpClient\HttpClientInterface: '@Symfony\Component\HttpClient\HttpClient'
    
  • Testing workflow:
    • Unit tests: mock HttpClientInterface and return MockResponse::fromJsonString() stubs.
    • Integration tests: inject TestHttpClient (via symfony/http-client’s testing tools) to assert request counts/URLs.
  • PSR-18 alignment: Use 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.
  • Client decorators: Add cross-cutting concerns (logging, retries, rate limiting) without breaking contracts:
    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);
        }
    }
    

Gotchas and Tips

  • ⚠️ Common trap: Forgetting a concrete client — HttpClientInterface alone won’t resolve. Ensure symfony/http-client is installed or another PSR-18 implementation.
  • ⚠️ Response methods: 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
    
  • Async ≠ automatic: The contract supports async via ResponseInterface::until() and cancel(), but basic request() calls are synchronous unless using AsyncHttpClient (from symfony/http-client) or PSR-18 async clients.
  • Debug tip: Enable debug mode in 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)%' }
    
  • Extensibility hook: Extend via composition — never extend the interface itself. Wrap HttpClientInterface in middleware/decorators for auth, caching (cache.php-cache), or retry logic (symfony/http-client-contract-compatible retry strategies).
  • PHP version: Requires PHP 8.1+. Laravel 10+ supports this — Laravel 9 and below may need symfony/psr-http-message-bridge to unify PSR-7/18 and Symfony message types.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport