Weave 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 Adapter Bundle Laravel Package

petrepatrasc/http-adapter-bundle

A Symfony bundle offering an HTTP adapter abstraction, letting applications wrap or swap HTTP client implementations behind a shared interface. Useful for decoupling code from specific HTTP libraries, though the project is low-activity and sparsely documented.

View on GitHub
Deep Wiki
Context7

Getting Started

First, a reality check. This is a Symfony 2–era bundle (WidopHttpAdapterBundle), not a Laravel package. It wires widop/http-adapter into Symfony's DI container via bundle configuration. As a Laravel developer, your first move is not composer require — it's deciding which of two situations you're in:

  • You're auditing/porting a legacy Symfony2 app → follow the Symfony path below.
  • You're building or maintaining a Laravel app → do not install it. Run a 30-minute Composer spike only to confirm the conflict, then reproduce the pattern with Illuminate\Support\Facades\Http or Guzzle. The adapter idea is worth stealing; the bundle is not.

If you are in a Symfony2 app, the onboarding loop is short:

composer require petrepatrasc/http-adapter-bundle
// app/AppKernel.php
$bundles = array(
    // ...
    new Widop\HttpAdapterBundle\WidopHttpAdapterBundle(),
);
# app/config/config.yml
widop_http_adapter:
    adapters:
        curl:
            class: Widop\HttpAdapterBundle\Adapter\CurlAdapter
        stream:
            class: Widop\HttpAdapterBundle\Adapter\StreamAdapter

Where to look first. Boot the app and inspect the container before writing any code:

app/console debug:container | grep -i adapter

The bundle's only real deliverable is the service layer it registers — a registry (widop_http_adapter) plus one service per configured adapter. The exact service ids/aliases are what you'll reference every day, so confirm them in your app rather than trusting any README. Then read the underlying widop/http-adapter docs: the HttpAdapterInterface methods (get, post, put, delete, head, options, patch) and the HttpResponse object are ~90% of daily usage.

First use case. Inject the registry, select a named adapter, call it, assert on the response object (status code + body), not the raw string:

$adapter  = $this->http->getAdapter('curl');
$response = $adapter->get('https://api.example.com/prices');

if (200 !== $response->getStatusCode()) {
    throw new \RuntimeException('Upstream failed: '.$response->getStatusCode());
}

$data = json_decode($response->getBody(), true);

That's the loop: register bundle → configure one adapter → inject registry → getAdapter() → read HttpResponse.

Implementation Patterns

Treat the registry as a factory, not a client. The bundle exists to let you pick a backend by name. Don't scatter getAdapter('curl') across controllers. Resolve once at the service-definition layer and inject the concrete adapter:

services:
    acme.api_adapter:
        factory: ['@widop_http_adapter', 'getAdapter']
        arguments: ['curl']

    acme.api_client:
        class: AcmeBundle\Http\ApiClient
        arguments: ['@acme.api_adapter']
class ApiClient
{
    public function __construct(HttpAdapterInterface $adapter) { $this->adapter = $adapter; }

    public function fetchPrice($sku)
    {
        return $this->adapter->get(sprintf('https://api.example.com/prices/%s', $sku));
    }
}

This is the single most important habit here: inject the adapter, never the registry, into business code. It keeps services testable and makes swapping curl→stream a one-line YAML change.

Choose adapters deliberately. Configure several side by side and route by call site:

Alias Use when
curl Default: fast, timeouts, parallel handles
stream No ext-curl, or you want allow_url_fopen semantics
guzzle You already depend on Guzzle and want its middleware
socket Low-level control, unusual ports/protocols

Wrap it in a decorator for cross-cutting concerns. The adapters are thin and offer no retry, backoff, or logging. Add those yourself:

class RetryingAdapter implements HttpAdapterInterface
{
    public function __construct(private HttpAdapterInterface $inner, private int $attempts = 3) {}

    public function get($url, array $headers = array()) {
        $tries = 0;
        do {
            $res = $this->inner->get($url, $headers);
            if ($res->getStatusCode() < 500) return $res;
        } while (++$tries < $this->attempts);
        return $res;
    }
    // delegate remaining methods to $this->inner
}

Map HttpResponse to a domain DTO at the boundary. Don't let a legacy HTTP response object leak into controllers or domain services. Decode once, validate, return your own value object — this is also what makes the eventual replacement migration mechanical.

Environment-specific configuration. Point dev at stream (easy to inspect) and prod at curl, keeping the same adapter alias and interface so no application code changes.

Laravel translation of the same pattern. If you're deliberately rebuilding this idiom, bind an interface in a service provider and back it with the framework client:

// app/Providers/HttpServiceProvider.php
$this->app->bind(PricingClient::class, fn () => new PricingClient(
    Http::baseUrl(config('services.pricing.url'))->timeout(5)
));

Constructor-injected, swappable, testable with Http::fake() — the same architectural payoff without the Symfony2 baggage.

Gotchas and Tips

  • Composer will fight you. The bundle targets Symfony2 (end-of-life) and its declared PHP constraints will likely conflict with modern PHP/Laravel. Expect resolution failures; treat that as a signal, not a puzzle to solve.
  • Installing is not the same as loading. Even if dependencies resolve, Laravel's kernel never registers Symfony bundles, so no service definitions load. There is no shim worth writing — reimplement instead.
  • Verify service ids, don't assume them. IDs and aliases vary across versions and config shapes. debug:container | grep -i adapter is your ground truth; a wrong alias produces a confusing container compile error rather than a clear "adapter not found."
  • The config class: key expects an FQCN. Typos there surface at container compile time, not at request time — read the full compile error, the useful line is usually not the last one.
  • Zero timeouts by default. The underlying adapters do not impose sensible timeouts for you. A hanging upstream will hang your request (or your worker). Set timeouts at the adapter/config level or in your decorator.
  • No retries, middleware, pooling, async, or observability. If you need any of these, you are now the maintainer of that functionality. Budget for it explicitly rather than discovering it in production.
  • Response API naming drifts. Docs and examples for widop/http-adapter mix getBody()/getContent() across versions. Check the installed interface rather than copying snippets — and write one adapter integration test that pins the behavior.
  • Zero stars, zero dependents, no upstream activity. Security patches and PHP compatibility updates become your responsibility. For a Laravel shop this is a disqualified strategic dependency; for a frozen Symfony2 app it's a documented, time-boxed liability.
  • Extension point that actually holds up: implement HttpAdapterInterface (or decorate an existing adapter) rather than forking. It keeps your call sites portable and makes the swap to Guzzle/Symfony HttpClient a single new class.
  • Isolate before you migrate. Wrap every call behind an internal interface with tests around the boundary, replace the implementation, then delete the bundle. The most valuable thing this package gives you is a working example of why that boundary is worth having — the code itself is not the deliverable.
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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk