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:

  • Decoupling: Aligns perfectly with Laravel’s service container and dependency injection (DI) principles, enabling HTTP client abstraction. Ideal for microservices, SDKs, or projects requiring interchangeable HTTP clients (e.g., switching from Guzzle to Symfony HttpClient).
  • PSR-18 Compliance: Leverages Symfony’s battle-tested contracts (which implement PSR-18), ensuring compatibility with Laravel’s Http facade via adapters (e.g., php-http/guzzle7-adapter or symfony/psr-http-message-bridge). Reduces custom interface code.
  • Laravel Integration: Not a drop-in replacement for Laravel’s Http facade (which uses Guzzle under the hood), but can coexist via service binding. Requires explicit refactoring of facade-dependent code to use HttpClientInterface.
  • Async/Sync Flexibility: Supports both synchronous and asynchronous operations (via ResponseInterface::until()), but async requires additional setup (e.g., symfony/http-client’s AsyncHttpClient).

Integration feasibility:

  • Low Effort for New Projects: Minimal overhead for greenfield Laravel apps adopting interface-first design. Requires:
    1. Installing symfony/http-client-contracts + a concrete client (e.g., symfony/http-client or guzzlehttp/guzzle).
    2. Binding HttpClientInterface to the concrete client in Laravel’s service container.
  • High Effort for Legacy Code: Existing Laravel apps using Http::get()/Http::post() directly will need:
    • Refactoring to inject HttpClientInterface into services.
    • Adapter layers for facade-to-contract conversion (e.g., Http::adapter() or custom wrappers).
  • Testing: Simplifies mocking/stubbing with MockHttpClient or TestHttpClient, but requires updating test doubles to match the interface.

Technical risk:

  • Breaking Changes: Laravel’s Http facade is tightly coupled to Guzzle. Replacing it with HttpClientInterface may expose edge cases (e.g., middleware, events, or Guzzle-specific features like onStats).
  • Performance Overhead: Decorators (e.g., logging, retries) add latency. Benchmark critical paths if using symfony/http-client (which supports HTTP/2 and connection pooling).
  • PHP 8.1+ Requirement: Blocks adoption in Laravel 9.x or older (unless using bridges like symfony/psr-http-message-bridge).
  • Missing Implementations: The package provides only interfaces—forgetting to install a concrete client (e.g., symfony/http-client) will cause runtime errors.

Key questions:

  1. Migration Strategy: Should we replace Laravel’s Http facade entirely, or introduce HttpClientInterface as a parallel abstraction for new services?
  2. Concrete Client Choice:
    • Use symfony/http-client for async/HTTP2 features?
    • Stick with Guzzle for existing middleware/plugins?
  3. Testing Impact: How will this affect existing PHPUnit tests using Http::fake() or Guzzle mocks?
  4. Async Needs: Do we need async support (e.g., for background jobs), or is synchronous sufficient?
  5. Adapter Gaps: Are there unsupported Laravel features (e.g., Http::macro()) that would require custom adapters?

Integration Approach

Stack fit:

  • Laravel 10+: Native support for PHP 8.1+ and PSR-18/PSR-7 interoperability. Works seamlessly with:
    • Symfony’s HttpClient (for async/HTTP2).
    • Guzzle (via guzzlehttp/psr7 or php-http/guzzle7-adapter).
    • Laravel’s Http facade (via adapter layer).
  • Laravel 9.x: Possible with symfony/psr-http-message-bridge to unify PSR-7/Symfony message types, but adds complexity.
  • Non-Laravel PHP: Framework-agnostic; ideal for reusable libraries or SDKs consumed by Laravel.

Migration path:

  1. Phase 1: New Services Only
    • Introduce HttpClientInterface in new services/modules.
    • Bind to symfony/http-client or Guzzle in config/app.php:
      'HttpClientInterface' => fn() => new \Symfony\Component\HttpClient\HttpClient(),
      
    • Use php-http/discovery for auto-discovery of installed clients.
  2. Phase 2: Gradual Refactoring
    • Replace Http::get() calls with HttpClientInterface in critical paths (e.g., API clients).
    • Create adapter classes to wrap Laravel’s Http facade:
      class LaravelHttpClient implements HttpClientInterface {
          public function request(string $method, string $url, array $options = []): ResponseInterface {
              return new LaravelResponse(Http::{$method}($url, $options));
          }
      }
      
  3. Phase 3: Full Replacement
    • Deprecate Http facade in favor of HttpClientInterface.
    • Update middleware/events to work with the new contract.

Compatibility:

  • Laravel-Specific Features:
    • Middleware: Laravel’s HTTP middleware (e.g., TrustProxies) won’t work directly. Use Symfony’s HttpClient middleware or custom decorators.
    • Events: Http::on() events require adapter translation to HttpClientInterface.
    • Macros: Http::macro() is facade-specific; replace with service providers or decorators.
  • PSR Compliance: Fully compatible with PSR-18 (ClientInterface) and PSR-7 (MessageInterface), enabling interoperability with other libraries (e.g., php-http/client).

Sequencing:

  1. Start with SDKs/Libraries: Adopt in reusable code (e.g., API clients) first to validate the pattern.
  2. Critical Paths: Refactor high-impact HTTP calls (e.g., payment gateways) before low-risk endpoints.
  3. Testing: Update test suites to use MockHttpClient or TestHttpClient before migrating production code.
  4. Deprecate Facade: Once 80% of HTTP calls use HttpClientInterface, deprecate Http:: in favor of the new contract.

Operational Impact

Maintenance:

  • Reduced Vendor Lock-in: Switching HTTP clients (e.g., Guzzle → Symfony HttpClient) requires only service container updates, not business logic changes.
  • Consistent Error Handling: Symfony’s contracts enforce standardized error responses (e.g., HttpClientException for non-2xx statuses), reducing ad-hoc error handling code.
  • Decorator Pattern: Cross-cutting concerns (logging, retries) are easier to maintain via decorators than middleware or facade macros.

Support:

  • Debugging: Symfony’s HttpClient provides detailed debug output (enable via HttpClient::create(['debug' => true])). Laravel’s Http facade lacks comparable tooling.
  • Community: Symfony’s ecosystem offers mature debugging tools (e.g., symfony/profiler) and community support for HTTP client issues.
  • Laravel-Specific Gaps: Support for Laravel’s unique features (e.g., Http::retry()) may require custom adapters or community packages.

Scaling:

  • Connection Pooling: symfony/http-client supports connection pooling and HTTP/2, improving performance under load. Guzzle requires manual tuning for similar benefits.
  • Async Operations: Enables non-blocking HTTP calls for background jobs or real-time features (e.g., WebSockets). Requires AsyncHttpClient or PSR-18 async clients.
  • Resource Usage: Decorators (e.g., retries, caching) add memory/CPU overhead. Monitor critical paths during load testing.

Failure Modes:

  • Missing Concrete Client: Forgetting to bind HttpClientInterface to a concrete implementation (e.g., symfony/http-client) causes ClassNotFoundException.
  • Response Handling: ResponseInterface::toArray() throws on empty bodies or non-2xx statuses. Mitigate with:
    $response = $client->request('GET', $url, ['throw' => false]);
    if ($response->getStatusCode() !== 200) { /* handle error */ }
    
  • Async Deadlocks: Improper use of ResponseInterface::until() or cancel() can hang requests. Use timeouts and cancellation tokens.
  • Middleware Conflicts: Laravel’s HTTP middleware may not translate cleanly to Symfony’s decorators, leading to unexpected request/response behavior.

Ramp-up:

  • Engineering Onboarding: Developers familiar with Laravel’s Http facade will need training on:
    • Interface-based design (no direct Http::get() calls).
    • Symfony’s response handling (e.g., getStatusCode() before toArray()).
    • Decorator pattern for cross-cutting concerns.
  • Documentation: Create internal docs for:
    • Adapter patterns (e.g., wrapping Http facade).
    • Debugging async requests.
    • Common pitfalls (e
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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager