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

Httplug Laravel Package

php-http/httplug

HTTPlug provides HTTP client abstraction interfaces for PHP, built on PSR-7 messages. Defines async HttpAsyncClient plus a sync HttpClient similar to PSR-18, enabling libraries to stay client-agnostic while supporting multiple HTTP implementations.

View on GitHub
Deep Wiki
Context7

Getting Started

HTTPlug defines two core interfaces for HTTP clients: HttpClient (synchronous) and HttpAsyncClient (asynchronous), both building on PSR-7 messages and returning PSR-7 responses. As of v2.4.0, HTTPlug is effectively a transition layer—the package authors now recommend using PSR-18 directly for synchronous clients, and only reach for HTTPlug if you need async support or legacy compatibility.

Start by installing:

composer require php-http/httplug php-http/discovery
  • httplug: defines the interfaces
  • discovery: enables auto-discovery of installed HTTP clients (e.g., Guzzle, curl, React)

The first use case is typically resolving a client via HTTPlug’s discovery mechanism:

use Http\Discovery\HttpClientDiscovery;

$client = HttpClientDiscovery::find();
$response = $client->sendRequest($psr7Request);

💡 Prefer HttpClientDiscovery::find() over manual instantiation when building reusable packages—this keeps client selection decoupled.

Implementation Patterns

For New Apps: Use PSR-18, Not HTTPlug

If you only need synchronous requests (95% of apps), just depend on psr/http-client and use Psr\Http\Client\ClientInterface. HTTPlug’s HttpClient now mirrors PSR-18 and is deprecated—its inclusion is mainly for backwards compatibility.

For Async Workflows: Leverage HttpAsyncClient

Use HttpAsyncClient when you need concurrency (e.g., batch external API calls, background sync tasks):

use Http\Client\HttpAsyncClient;
use Http\Discovery\Psr17Factory;
use function Http\Promise\unwrap;

// Build multiple requests
$requests = array_map(
    fn ($url) => Psr17Factory::createRequestFactory()->createRequest('GET', $url),
    ['https://api.a.com', 'https://api.b.com']
);

/** @var HttpAsyncClient $asyncClient */
$responsesPromise = $asyncClient->sendAsyncRequests($requests);

// Wait for all
$responses = unwrap($responsesPromise);

You’ll typically inject HttpAsyncClient (via DI) and combine with php-http/promise utilities like unwrap() or HttpFulfilledPromise.

Plugin Architecture (Legacy/Middleware)

HTTPlug ships with plugins (php-http/plugins) to add retries, logging, etc. Use HTTPlug’s promise system to support async:

use Http\Client\Common\Plugin\RetryPlugin;
use Http\Client\Common\PluginClient;

$plugins = [new RetryPlugin()];
$client = new PluginClient($decoratedClient, $plugins);

⚠️ Plugins rely on Http\Promise\Promise (not PSR-18), so async logic remains compatible.

Gotchas and Tips

⚠️ Deprecation & Migration Risks

  • Http\Client\HttpClient is deprecated as of 2.4.0. New code should use Psr\Http\Client\ClientInterface for sync.
  • Exception hierarchy changed in v2.1.0: NetworkException no longer extends RequestException (aligns with PSR-18). Update catch blocks accordingly.
  • Nullable parameter warnings in PHP 8.4 are fixed in 2.4.1—ensure you’re not on an older patch version.

🔍 Debugging Async Code

  • Async responses throw exceptions in the promise, not inline. Always unwrap() or use then() to surface failures:
    $promise = $asyncClient->sendAsyncRequest($request);
    try {
        $response = $promise->wait(); // or unwrap([$promise])[0]
    } catch (\Throwable $e) {
        // Network exceptions end up here
    }
    
  • The $onRejected callback in v2.3.0+ can return another promise—use this for smart retry logic:
    $promise = $asyncClient->sendAsyncRequest($request);
    $retryPromise = $promise->then(
        fn ($r) => $r,
        fn ($e) => $shouldRetry ? $this->retry($e) : throw $e
    );
    

🛠 Configuration & Extensions

  • Always pair httplug with a client implementation (e.g., php-http/guzzle6-adapter).
  • Use php-http/discovery cautiously in production—it scans installed packages, which adds overhead. Prefer explicit client binding via DI in critical paths.
  • To extend discovery, configure a custom discovery class via httplug Discovery configuration (not covered in README—requires subclassing DiscoveryStrategy).
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