weblabel/http-client-bundle
Weblabel HTTP Client Bundle provides a configurable HTTP client integration for PHP applications, with service wiring and sensible defaults for outbound API requests. It centralizes client configuration and simplifies setup for projects needing a lightweight, reusable HTTP layer.
Before anything else: this is a Symfony bundle, not a Laravel package. There is no service provider, no auto-discovery, no facade, and no config/ publish step. A composer require weblabel/http-client-bundle in a Laravel app will install files you cannot bootstrap through Laravel's container without manual wiring. Treat the "Laravel developer" framing as: what would I actually do with this in a Laravel codebase, and when would I reach for it?
In a Symfony app (its intended home):
composer require weblabel/http-client-bundleconfig/bundles.php:
Weblabel\HttpClientBundle\WeblabelHttpClientBundle::class => ['all' => true],
config/packages/weblabel_http_client.yaml (verify the exact root key by reading src/DependencyInjection/Configuration.php — the README is thin and the tree is authoritative).Where to look first, in order:
src/DependencyInjection/Configuration.php — every config key and default.src/DependencyInjection/WeblabelHttpClientExtension.php — how services are built and aliased.src/Resources/config/*.xml|yaml — the actual service IDs and constructor arguments.In a Laravel app: don't install it casually. Laravel already ships Illuminate\Support\Facades\Http (Guzzle-backed) with retry(), timeout(), withHeaders(), fakeable tests, and first-class container binding. The only legitimate reasons to touch this bundle from Laravel are (a) you're extracting a shared library used by both a Symfony and a Laravel service, or (b) you genuinely want the bundle's specific wrapper behavior. Otherwise, the honest first move is to skip it.
Symfony-native usage (the pattern the bundle is built for):
config/packages/weblabel_http_client.yaml and vary it per environment via .env interpolation rather than hardcoding. This is the single biggest win of using a bundle over new Client().config/services.yaml:
Weblabel\HttpClientBundle\Contract\ClientInterface:
alias: weblabel.http_client
Check the exact service ID in the extension class first — guessing IDs is the #1 source of ServiceNotFoundException.Decorator pattern for cross-cutting concerns. Because the bundle is thin, wrap its client in your own class implementing the same interface and add logging, retries, or circuit-breaking there. This keeps the vendor surface area small and is easier to test than monkey-patching config.
Bridge pattern for Laravel. If you must use it:
config('services.weblabel.*').WeblabelClientInterface and inject that into jobs/controllers — never inject the vendor class directly.Http:: is a one-file change.Testing. In Symfony, mock the underlying transport (Symfony HttpClient's MockHttpClient or a PSR-18 mock) rather than the wrapper. In Laravel, if you're bridging, use Http::fake() only if the bundle ultimately routes through Guzzle/Symfony HttpClient — verify this first. Otherwise, bind a fake implementation of your adapter interface.
Job/queue integration tip: for Laravel queues, always set explicit timeouts on the injected client and wrap calls in try/catch that translates transport exceptions into your domain exceptions. The bundle does not appear to impose sane defaults.
symfony/framework-bundle and symfony/http-client that may conflict with modern Symfony or with PHP 8.2+. Run composer why-not early; expect to fork or shim.Configuration.php is the source of truth. Symfony will silently ignore typo'd keys in some legacy extension setups — enable framework.php_errors and check the container with bin/console debug:config weblabel_http_client.$client->request(...)->getContent() throws), whereas Guzzle needs http_errors => false to return status codes. Mismatched expectations here cause silent production bugs.Http::withToken(...)->baseUrl(...)->timeout(...)->retry(...)->get(...). Design for that swap from day one.How can I help you explore Laravel packages today?