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 Implementations Laravel Package

psr-discovery/http-client-implementations

Discovers an installed PSR-18 HTTP client at runtime by checking for well-known implementations and returning the first available instance. Ideal for SDKs/libraries to support PSR-18 without hard dependencies or extra user configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • PSR-18 Alignment: The package adheres to the PSR-18 HTTP Client standard, making it a natural fit for Laravel applications (which already leverage PSR standards like PSR-4, PSR-11, and PSR-17). This ensures compatibility with Laravel’s dependency injection and service container.
  • Decoupling Benefit: Eliminates hard dependencies on specific HTTP clients (e.g., Guzzle, Symfony HTTP Client) in SDKs or libraries, reducing vendor lock-in and simplifying maintenance.
  • Laravel Ecosystem Synergy: Works seamlessly with Laravel’s existing PSR-compliant components (e.g., illuminate/http-client, symfony/http-client), which are already supported by this package.

Integration Feasibility

  • Low Friction: Requires only a single composer require and minimal boilerplate (Discover::httpClient()). No configuration files or complex setup.
  • Backward Compatibility: Can coexist with Laravel’s built-in HTTP clients (e.g., HttpClient facade) without conflicts, as it operates at the PSR-18 interface level.
  • Testing Support: Prioritizes mock implementations (e.g., php-http/mock-client) for unit testing, aligning with Laravel’s testing best practices (e.g., Mockery or PHPUnit mocks).

Technical Risk

  • Dependency on Host Environment: Discovery fails gracefully (returns null) if no PSR-18 implementation is installed. This requires fallback logic in the TPM’s architecture (e.g., defaulting to Laravel’s HttpClient or throwing a descriptive exception).
  • Performance Overhead: Runtime class discovery (via class_exists() checks) adds minimal overhead, but singleton caching (Discover::httpClient(singleton: true)) mitigates this for repeated calls.
  • Version Conflicts: Supports multiple versions of clients (e.g., Guzzle 7/8, Symfony 6/7/8), but Laravel’s dependency constraints (e.g., ^9.0 requiring Symfony 6+) may limit flexibility. Validate compatibility during integration.
  • Mocking Behavior: Mock clients take priority in development, which may break production-like behavior in tests if not explicitly excluded (e.g., via Clients::use('symfony/http-client')).

Key Questions

  1. Primary Use Case:

    • Is this for internal SDKs/libraries (decoupling) or application-level HTTP calls (replacing Laravel’s HttpClient)?
    • Impact: Affects whether to enforce a specific client (e.g., Clients::use('guzzlehttp/guzzle')) or rely on discovery.
  2. Fallback Strategy:

    • How will the system handle null returns (e.g., no PSR-18 client installed)?
    • Options: Default to Laravel’s HttpClient, throw an exception, or require explicit client installation.
  3. Testing Strategy:

    • Will mock clients be automatically prioritized in tests, or should they be opt-in (e.g., via environment flags)?
    • Risk: Unintended mock usage in CI/CD pipelines.
  4. Performance Sensitivity:

    • Are HTTP clients instantiated frequently (e.g., per-request) or once (e.g., singleton)?
    • Recommendation: Use singleton: true for high-frequency use cases.
  5. Client Preference:

    • Should the TPM enforce a specific client (e.g., Guzzle for features like middleware) or let discovery decide?
    • Tradeoff: Enforcement simplifies debugging but reduces flexibility.

Integration Approach

Stack Fit

  • Laravel Compatibility:

    • PSR-18 Clients: Works with Laravel’s existing clients (e.g., symfony/http-client in Laravel 9+) and third-party clients (e.g., Guzzle).
    • Service Container: Can be registered as a bindable service in Laravel’s container:
      $this->app->bind(\Psr\Http\Client\ClientInterface::class, function ($app) {
          return Discover::httpClient(singleton: true);
      });
      
    • Facades/Helpers: Wrap Discover::httpClient() in a custom facade (e.g., HttpClientDiscovery) for consistency with Laravel’s Http facade.
  • Existing Laravel HTTP Stack:

    • Coexistence: Can replace only the PSR-18 layer while keeping Laravel’s HttpClient facade for convenience methods (e.g., get(), post()).
    • Migration Path: Start by using Discover::httpClient() in new services/SDKs, then gradually replace direct client instantiations.

Migration Path

  1. Phase 1: Discovery in SDKs/Libraries

    • Replace hardcoded client instantiations (e.g., new GuzzleHttp\Client()) with Discover::httpClient() in internal libraries or third-party SDKs.
    • Example: A PaymentGateway service using this package instead of new GuzzleHttp\Client().
  2. Phase 2: Application-Level Adoption

    • Register the discovered client in Laravel’s container (see above).
    • Replace direct HttpClient usage in services/controllers with the discovered client where PSR-18 compliance is sufficient.
  3. Phase 3: Testing Integration

    • Configure mock clients in phpunit.xml or composer.json dev dependencies:
      "require-dev": {
          "php-http/mock-client": "^1.5"
      }
      
    • Use Clients::use('php-http/mock-client') in tests to enforce mock usage.

Compatibility

  • Laravel Versions:

    • Laravel 9+: Native support for Symfony HTTP Client (v6+) and PSR-18.
    • Laravel 8: Requires manual installation of a PSR-18 client (e.g., symfony/http-client:^5.0).
    • Recommendation: Target Laravel 9+ for seamless integration.
  • Client-Specific Features:

    • Some clients (e.g., Guzzle) offer middleware, retries, or plugins. Ensure these are not lost during migration (e.g., by configuring the client post-discovery).
    • Example:
      $client = Discover::httpClient();
      $client = $client->withConfig(['timeout' => 30]); // Client-specific config
      
  • Legacy Code:

    • Non-PSR-18 HTTP calls (e.g., file_get_contents(), curl_init()) remain unaffected.

Sequencing

  1. Dependency Installation:

    • Add psr-discovery/http-client-implementations and a primary PSR-18 client (e.g., symfony/http-client).
    • Example:
      composer require psr-discovery/http-client-implementations symfony/http-client
      
  2. Service Registration:

    • Bind the discovered client to Laravel’s container (as shown above).
  3. Gradual Replacement:

    • Start with new code, then refactor legacy services to use the discovered client.
  4. Testing Setup:

    • Configure mock clients for unit tests.
    • Add integration tests to verify discovery behavior (e.g., fallback to default client).
  5. Monitoring:

    • Log discovery failures (e.g., null returns) to identify missing clients early.

Operational Impact

Maintenance

  • Pros:

    • Reduced Boilerplate: No need to manage client versions or configurations in multiple places.
    • Centralized Updates: Updating the PSR-18 client (e.g., Guzzle 8) requires only a composer update in the host project.
    • Consistent Behavior: Discovery ensures one source of truth for HTTP clients across the application.
  • Cons:

    • Debugging Complexity: Discovery failures (e.g., null returns) require checking multiple dependencies (host project + installed clients).
    • Mock Management: Mock clients must be explicitly managed in dev dependencies to avoid production leaks.
  • Recommendations:

    • Document the discovery flow (e.g., "If Discover::httpClient() returns null, install symfony/http-client").
    • Add a health check (e.g., a console command) to verify PSR-18 client availability in CI/CD.

Support

  • Troubleshooting:
    • Common Issues:
      • Missing PSR-18 client → Add a fallback or enforce installation.
      • Mock client interfering in production → Use Clients::use('symfony/http-client') explicitly.
      • Performance bottlenecks → Enable singleton caching.
    • Tools:
      • Use composer why-not psr-discovery/http-client-implementations to debug dependency conflicts.
      • Log discovery results for debugging:
        $client = Discover::httpClient();
        if (!$client) {
            logger()->error('No PSR-18
        
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky