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

Technical Evaluation

Architecture Fit

  • High compatibility with Laravel’s dependency injection (DI) and service container, enabling decoupled HTTP client logic via HttpClientInterface.
  • PSR-18 alignment ensures interoperability with Laravel’s built-in Http facade (via adapters like php-http/guzzle7-adapter) or third-party clients (e.g., Guzzle, Symfony HttpClient).
  • Not a drop-in replacement for Laravel’s Http:: facade—requires refactoring to adopt interface-based design. Ideal for new services, SDKs, or microservices where client interchangeability is critical.
  • Symfony ecosystem synergy: Best suited for projects already using Symfony components (e.g., symfony/http-client) or planning to migrate from Guzzle to Symfony’s client.

Integration Feasibility

  • Low effort for new projects: Minimal boilerplate if adopting interface-first design from day one.
  • Moderate effort for existing Laravel apps:
    • Requires service provider binding to resolve HttpClientInterface to a concrete client (e.g., symfony/http-client or Guzzle with PSR-18 bridge).
    • Facade refactoring: Replace direct Http::get() calls with injected HttpClientInterface in services.
    • Testing overhead: Mocking HttpClientInterface is straightforward but requires setup (e.g., MockHttpClient or TestHttpClient).
  • Dependency chain:
    • Core package: symfony/http-client-contracts (interfaces only).
    • Concrete client: symfony/http-client (recommended) or guzzlehttp/guzzle + guzzlehttp/psr7.
    • Optional: php-http/discovery for auto-wiring or symfony/cache for response caching.

Technical Risk

  • Breaking changes: Symfony contracts are stable, but Laravel-specific integrations (e.g., facade adapters) may require updates if Laravel evolves its HTTP stack.
  • Performance implications:
    • Async support: Requires explicit use of AsyncHttpClient (not enabled by default).
    • Connection pooling: Configured via Symfony’s HttpClient (not the contracts layer).
  • Error handling: Responses throw exceptions by default on non-2xx statuses; explicit throw: false or getStatusCode() checks are needed.
  • PHP 8.1+ requirement: Laravel 10+ is compatible; older versions may need polyfills (e.g., symfony/psr-http-message-bridge).

Key Questions

  1. Client Strategy:
    • Will the team use symfony/http-client (feature-rich, async) or Guzzle (lightweight, familiar)?
    • Are there plans for HTTP/2, async requests, or connection pooling?
  2. Facade vs. Interface:
    • Should Laravel’s Http:: facade be deprecated in favor of HttpClientInterface, or retained as a wrapper?
  3. Testing Strategy:
    • How will mock responses be generated (e.g., MockHttpClient, TestHttpClient, or custom stubs)?
  4. Migration Path:
    • What’s the timeline for refactoring existing Http:: calls to interface-based services?
  5. Cross-Cutting Concerns:
    • Will decorators (e.g., logging, retries) be implemented as middleware or via Laravel’s service bindings?
  6. PSR Compliance:
    • Should the project enforce PSR-18 (via psr/http-client) or stick to Symfony’s contracts for broader Symfony ecosystem compatibility?

Integration Approach

Stack Fit

  • Laravel 10+: Native support for PHP 8.1+ and Symfony contracts. Use symfony/http-client for full feature parity or Guzzle for simplicity.
  • Laravel 9 or below: Requires symfony/psr-http-message-bridge to unify PSR-7/18 message types and may need facade adapters.
  • Non-Laravel PHP: Ideal for framework-agnostic libraries or Symfony-based microservices.
  • Testing Stack: Integrates seamlessly with PHPUnit via MockHttpClient or Pest via TestHttpClient.

Migration Path

  1. Phase 1: Interface Adoption (Low Risk)

    • Add symfony/http-client-contracts and a concrete client (e.g., symfony/http-client).
    • Create a service provider to bind HttpClientInterface to the concrete client:
      // app/Providers/AppServiceProvider.php
      public function register()
      {
          $this->app->bind(
              HttpClientInterface::class,
              fn() => new \Symfony\Component\HttpClient\HttpClient()
          );
      }
      
    • Refactor new services to accept HttpClientInterface in constructors.
  2. Phase 2: Facade Deprecation (Medium Risk)

    • Replace Http::get() calls with injected HttpClientInterface in critical paths (e.g., API clients, background jobs).
    • Use Laravel’s facade adapters (if available) or create a wrapper facade for gradual migration:
      // app/Facades/HttpClient.php
      public static function request(string $method, string $url, array $options = []): ResponseInterface
      {
          return app(HttpClientInterface::class)->request($method, $url, $options);
      }
      
  3. Phase 3: Cross-Cutting Concerns (Optional)

    • Implement decorators for retries, caching, or logging:
      // 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);
          }
      }
      
    • Bind decorators in the service container:
      $this->app->bind(HttpClientInterface::class, fn() => new LoggingHttpClient(
          new \Symfony\Component\HttpClient\HttpClient()
      ));
      
  4. Phase 4: Testing and Validation

    • Replace Http::fake() with MockHttpClient or TestHttpClient in unit tests.
    • Validate integration tests with real HTTP interactions (e.g., using TestHttpClient to assert request/response cycles).

Compatibility

  • Symfony HttpClient: Full feature parity (async, pooling, middleware).
  • Guzzle: Requires guzzlehttp/psr7 and php-http/guzzle7-adapter for PSR-18 compliance.
  • Laravel Http Client: Use php-http/laravel-adapter to bridge Laravel’s Http facade to HttpClientInterface.
  • PSR-18: Symfony’s contracts implement PSR-18, ensuring compatibility with other PSR-18 clients (e.g., php-http/client).

Sequencing

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

Operational Impact

Maintenance

  • Pros:
    • Reduced vendor lock-in: Swap clients (e.g., Guzzle → Symfony HttpClient) without code changes.
    • Standardized error handling: Consistent exceptions across HTTP clients (e.g., HttpClientException).
    • Lower technical debt: No need to maintain custom interfaces or adapters.
  • Cons:
    • Additional abstraction layer: Debugging may require tracing through decorators or middleware.
    • Symfony dependency: Projects using only Guzzle may introduce unnecessary complexity.

Support

  • Engineering:
    • Easier onboarding: New developers familiar with Symfony or PSR-18 will adapt quickly.
    • Testing: Mocking HttpClientInterface is straightforward but requires initial setup.
  • Operations:
    • Client-specific configs: Symfony HttpClient requires YAML/array configs for pooling, retries, etc.
    • Async debugging: Async requests may need additional tooling (e.g., until() callbacks).

Scaling

  • Performance:
    • Connection pooling: Configured via Symfony HttpClient (not the contracts layer).
    • Async support: Enabled via AsyncHttpClient but requires explicit opt-in.
    • Caching: Integrate with symfony/cache or Laravel’s cache for response caching.
  • Resource Usage:

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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle