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

freshcells/guzzle-bundle

A Symfony bundle that integrates the Guzzle HTTP client into your application, offering service configuration and dependency injection so you can make and manage outgoing HTTP requests cleanly within Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Three steps and you have a configured, profiler-visible client instead of a new Client() scattered across your services.

composer require freshcells/guzzle-bundle
// config/bundles.php
return [
    // ...
    Csa\Bundle\GuzzleBundle\CsaGuzzleBundle::class => ['all' => true],
];
# config/packages/csa_guzzle.yaml
csa_guzzle:
    clients:
        github:
            config:
                base_url: 'https://api.github.com'
                timeout: 5
                connect_timeout: 2
                headers:
                    Accept: 'application/vnd.github.v3+json'
                    User-Agent: 'my-app/1.0'

The bundle registers each client as a service named csa_guzzle.client.<name>, so you inject @csa_guzzle.client.github wherever you need it. If you configure a client called default, the bundle also wires a default client service you can alias for autowiring:

services:
    GuzzleHttp\ClientInterface: '@csa_guzzle.client.github'

First use case: replace every hand-rolled new GuzzleHttp\Client([...]) in your app with a named, config-driven client. You immediately gain a web-debug-toolbar panel showing every outbound request (URL, headers, status, timing, body), centralised timeouts, and one place to add auth headers.

Where to look first: DependencyInjection/Configuration.php in the vendor directory. It is the authoritative list of what you may put under clients.<name>.config — don't guess at option names, read the tree.

Implementation Patterns

One named client per upstream. github, stripe, internal_erp — each with its own base_url, auth, and timeouts. Resist the single "generic" client; per-upstream clients make middleware and mocking tractable.

Middleware is the main extension point. Write a __invoke(callable $handler): callable class and tag it:

services:
    App\Guzzle\CorrelationIdMiddleware:
        tags:
            - { name: csa_guzzle.middleware, alias: correlation_id, priority: 10 }

This is where auth-token refresh, correlation IDs, structured logging, and Guzzle's own RetryMiddleware belong. Tagged middleware applies to the bundle's client stack; priority controls ordering, which matters — auth middleware must run before logging middleware or your logs will show unauthenticated requests.

Events for cross-cutting instrumentation. The bundle dispatches Symfony events around requests (before/after/error — check the bundle's events class for the exact constant names before wiring listeners). Prefer a listener over middleware when the concern is observability-only and shouldn't be able to mutate the request.

Testing with a mock handler. In config/packages/test/csa_guzzle.yaml, redefine the client service with a MockHandler + HistoryMiddleware handler stack, or build test clients through the bundle's client factory service. Assert on $history rather than hitting the network. Keep a small fixture of recorded responses per upstream so contract changes fail loudly.

Retries belong in a middleware, not in your service methods. A RetryMiddleware with exponential backoff on 429/5xx will save you more code and incidents than any wrapper class — but only around idempotent calls (see gotchas).

Laravel reality check: this is Symfony-only. In a Laravel app you'd get the same outcomes from the Http facade or a Guzzle client bound in a service provider; the bundle's config tree, profiler panel, and csa_guzzle.middleware tag have no equivalent there. The assessment below is only relevant to Symfony projects in your estate.

Gotchas and Tips

  • Traction is zero. No stars, no dependents. Pin an exact version in composer.json, check the last commit date and the Symfony version constraint before adopting, and keep a one-afternoon exit plan: plain Guzzle service definitions in services.yaml reproduce ~90% of the value.
  • Options live under clients.<name>.config. Flattening them to clients.<name>.base_url is the single most common first mistake. The config tree will usually reject unknown keys, which is a decent error message — read it rather than guessing.
  • Guzzle 6 vs 7. PSR-18's Psr\Http\Client\ClientInterface only exists from Guzzle 7. If you type-hint it, verify the resolved Guzzle version, or you'll get a confusing "service not found" for a client that demonstrably exists.
  • base_url semantics bite. Guzzle's base_uri resets the path on absolute-looking paths: /users discards any path prefix in the base. Use relative URIs (users) or the full URL, and test both.
  • http_errors defaults to true. 4xx and 5xx throw GuzzleHttp\Exception\RequestException. Either catch GuzzleException at the boundary or set http_errors: false and branch on status codes — don't let a 404 from a third party bubble up as a 500 in your app.
  • Retries + non-rewindable bodies. Guzzle cannot replay a streamed body. Call $request->getBody()->rewind() in the retry decision callback, and never retry POSTs that create resources.
  • Set both timeout and connect_timeout. Guzzle's default is 0 (infinite). An unresponsive upstream will otherwise hang a PHP-FPM worker until max_execution_time.
  • Profiler memory. The data collector holds request and response bodies in memory. It's debug-only, but on a dev machine hammering large payloads it will make the toolbar slow; there's no per-client opt-out, so be selective about what you call during local development.
  • Middleware alias collisions. Two tagged services with the same alias will silently shadow one another. Namespace your aliases (app.auth, app.logging).
  • Long-running processes. Don't enable debug/profiler middleware in Messenger workers or queue consumers; the accumulated history is a leak. This also applies to injecting a Guzzle client into long-lived services that cache responses.
  • The handler stack is not fully configurable from YAML. For exotic setups (custom handlers, Pool, cookies, curl options), get the client from the bundle's client factory or decorate csa_guzzle.client.<name> in services.yaml — the config tree only exposes the common surface.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib