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

Guzzle Http Bundle Laravel Package

m6web/guzzle-http-bundle

Symfony bundle that integrates the Guzzle HTTP client into your application. Configure Guzzle clients in bundle configuration, inject them as services, and make outbound HTTP calls cleanly. Built-in logging and Symfony profiler integration help you inspect and debug requests and responses.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and register

composer require m6web/guzzle-http-bundle
// config/bundles.php
return [
    // ...
    M6Web\Bundle\GuzzleHttpBundle\M6WebGuzzleHttpBundle::class => ['all' => true],
];

There is generally no Flex recipe, so config and registration are manual.

2. Declare your first client

# config/packages/m6_web_guzzle_http.yaml
m6_web_guzzle_http:            # confirm root key with config:dump-reference
    clients:
        github:
            base_uri: 'https://api.github.com'
            timeout: 3.0
            connect_timeout: 1.0
            headers:
                Accept: 'application/vnd.github+json'

3. Consume it

The bundle exposes one service per configured client, named <alias>.client.<name>:

# config/services.yaml
services:
    App\Api\GithubClient:
        arguments:
            $http: '@m6_web_guzzle_http.client.github'
final class GithubClient
{
    public function __construct(private \GuzzleHttp\ClientInterface $http) {}

    public function repository(string $owner, string $repo): array
    {
        return $this->http->get("/repos/$owner/$repo")->getBody()->getContents()
            |> json_decode(...); // or plain json_decode in PHP < 8.5
    }
}

4. Where to look first

Need Look at
Option tree / defaults bin/console config:dump-reference M6WebGuzzleHttpBundle
Exact service ids bin/console debug:container --show-private m6_web_guzzle_http
Real capabilities vendor/m6web/guzzle-http-bundle/README.md
Behaviour when docs are thin DependencyInjection/Configuration.php + DependencyInjection/*Extension.php
Runtime introspection Symfony profiler → the Guzzle panel (debug env only)

First use case: replace ad-hoc new Client([...]) scattered across services with a single declarative client per upstream, then hit one endpoint and check the profiler panel to confirm the request was captured.

Implementation Patterns

One client per upstream, named after the upstream. billing, github, internal-search. Resist a single generic api client with per-call base_uri overrides — the whole value of the bundle is that the transport contract lives in config, reviewable and diffable per environment.

Wrap Guzzle, don't leak it. The bundle hands you a GuzzleHttp\ClientInterface. Never inject it into a controller and never return ResponseInterface upward. Put a thin domain class in front of it that returns arrays/DTOs and owns error translation:

final class BillingClient
{
    public function __construct(private ClientInterface $http) {}

    public function invoice(string $id): Invoice
    {
        try {
            $res = $this->http->get("/invoices/$id");
        } catch (RequestException $e) {
            throw new BillingUnavailable($e->getMessage(), previous: $e);
        }
        return Invoice::fromArray(json_decode((string) $res->getBody(), true));
    }
}

Per-environment overrides. The bundle is pure config, so this is where it shines:

# config/packages/test/m6_web_guzzle_http.yaml
m6_web_guzzle_http:
    clients:
        github:
            base_uri: 'http://127.0.0.1:8081'
            timeout: 1.0

Point it at WireMock / a local stub server for integration tests, or override the service in services_test.yaml with a MockHandler-backed client for unit tests.

Cross-cutting concerns via middleware, not call sites. Add correlation IDs, structured request logging, and retry/backoff once. If your version of the bundle exposes handler-stack / middleware options in config, use them; otherwise decorate the service:

App\Api\CorrelatedGithubClient:
    decorates: m6_web_guzzle_http.client.github
    arguments: ['@.inner']

Fan-out with async. For N independent calls, requestAsync + Utils::settle (tolerates partial failures) or Pool (bounded concurrency) beats sequential calls, and per-client timeout config keeps one slow upstream from stalling the batch.

Typed aliases beat string ids. Define App\Api\GithubClient as the injection target and keep the bundle's service id in exactly one place (services.yaml). If you later drop the bundle, you change one alias.

Compiler pass for many clients. If tenants/environments generate dozens of clients, build the config in a PrependExtensionInterface extension or tag-and-collect rather than hand-writing YAML.

Gotchas and Tips

It is a small, low-traffic package (17 stars, zero known dependents). Expect no StackOverflow answers and sparse docs. Budget time to read the source — it is only a handful of classes — and treat it as a thin convenience layer, not infrastructure.

Confirm the config root key per version. Older releases use m6_web_guzzle_http, newer ones may use guzzle_http. Always verify with config:dump-reference rather than copying a snippet from a blog post; a wrong root key silently does nothing in some Symfony versions.

http_errors defaults to true. Guzzle throws RequestException on 4xx/5xx and ConnectException on transport failures. Decide centrally: either set http_errors: false in the client options and handle status codes explicitly, or catch inside your wrapper. Mixed approaches produce "sometimes it throws, sometimes it returns 500" bugs.

Timeouts are not optional. Guzzle's default timeout is effectively infinite. Always set both timeout and connect_timeout. A hung upstream in a queue worker is the classic incident this prevents.

Service ids are shared, stateful singletons. Mocking the client once and reusing it across tests leaks recorded history between cases. Build a fresh MockHandler per test (HandlerStack::create($mock) → new Client(['handler' => $stack])) and override the alias in the container.

The profiler panel is debug-only. Useful for local debugging, useless for production observability. Add your own middleware emitting metrics (duration, status class, upstream name) if you need SLOs.

Guzzle version compatibility. The bundle sits on top of Guzzle 6/7 semantics. Two distinct interfaces are in play — GuzzleHttp\ClientInterface and PSR-18's Psr\Http\Client\ClientInterface. Type-hint the one the bundle actually registers, and check composer.json constraints before a Symfony major upgrade; abandoned bundles are the usual casualty of those.

Handler stack ordering matters. Retry must wrap logging (or logging must wrap retry) depending on whether you want to log attempts or final outcomes. Getting this backwards is a silent source of misleading dashboards.

Don't inject HTTP clients into Doctrine listeners or entities. It creates container cycles and couples persistence to network availability. Keep HTTP at the edges: controllers, message handlers, console commands.

Migration escape hatch. Everything the bundle does can be reproduced with plain services.yaml:

services:
    app.github.guzzle:
        class: GuzzleHttp\Client
        arguments: [{ base_uri: '%env(GITHUB_BASE_URI)%', timeout: 3 }]

If you find yourself fighting the config schema, take that path — you keep the declarative client and lose only the profiler panel.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core