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

Guzzle Factory Laravel Package

graham-campbell/guzzle-factory

Simple factory for creating Guzzle HTTP clients with sensible defaults. One-liner client creation via GuzzleFactory::make(), with optional config like base_uri. Supports PHP 7.4–8.5 and integrates cleanly in modern PHP/Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require graham-campbell/guzzle-factory
    
  2. Register the factory in config/app.php under providers:

    GrahamCampbell\GuzzleFactory\GuzzleFactoryServiceProvider::class,
    
  3. Publish the config (optional but recommended for customization):

    php artisan vendor:publish --provider="GrahamCampbell\GuzzleFactory\GuzzleFactoryServiceProvider" --tag="config"
    

    This creates config/guzzle-factory.php with sensible defaults.

  4. First use case: Create a client in a controller or service:

    use GrahamCampbell\GuzzleFactory\Facades\GuzzleFactory;
    
    $client = GuzzleFactory::make(['base_uri' => 'https://api.example.com']);
    

Key Starting Points

  • Facade: Use GuzzleFactory::make() for quick client creation.
  • Service Container: Bind the factory to Laravel’s container for dependency injection:
    $this->app->singleton('guzzle.example', fn() => GuzzleFactory::make(['base_uri' => 'https://example.com']));
    
  • Config File: Customize defaults in config/guzzle-factory.php (e.g., timeout, retries, TLS settings).

Implementation Patterns

Core Workflows

1. Centralized Client Creation

  • Pattern: Define all API clients in a single config file or service provider.
  • Example:
    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->singleton('stripe.client', fn() =>
            GuzzleFactory::make(['base_uri' => 'https://api.stripe.com'])
        );
    }
    
  • Use Case: Inject stripe.client into services/controllers via constructor injection.

2. Dynamic Configuration via Config File

  • Pattern: Store API endpoints and defaults in config/services.php:
    'services' => [
        'stripe' => [
            'base_uri' => env('STRIPE_API_URL'),
            'timeout'  => 10,
        ],
        'paypal' => [
            'base_uri' => env('PAYPAL_API_URL'),
            'headers'  => ['Accept' => 'application/json'],
        ],
    ],
    
  • Implementation:
    $client = GuzzleFactory::make(config('services.stripe'));
    

3. Middleware Integration

  • Pattern: Attach middleware (e.g., auth, logging) via the handler stack.
  • Example:
    $client = GuzzleFactory::make(
        ['base_uri' => 'https://api.example.com'],
        null,
        static function (HandlerStack $stack) {
            $stack->push(
                Middleware::tap(static function ($request) {
                    $request = $request->withHeader('X-Custom-Header', 'value');
                    return $request;
                })
            );
        }
    );
    
  • Use Case: Add auth headers or logging to all requests for a specific client.

4. Transport Sharing for Performance

  • Pattern: Enable transport sharing for clients with frequent requests.
  • Example:
    $client = GuzzleFactory::make(
        ['base_uri' => 'https://api.example.com'],
        TransportSharing::HANDLER_PREFER // Best-effort sharing
    );
    
  • Use Case: High-frequency APIs (e.g., real-time data feeds).

5. Testing with Mocks

  • Pattern: Mock the factory in tests to avoid real HTTP calls.
  • Example:
    $this->app->instance('guzzle.example', Mockery::mock(GuzzleHttp\Client::class));
    
  • Use Case: Unit tests for services using Guzzle clients.

Integration Tips

Laravel-Specific

  • Service Container Binding: Bind clients to the container for easy dependency injection:
    $this->app->bind('api.client', fn() =>
        GuzzleFactory::make(['base_uri' => config('services.api.url')])
    );
    
  • Config Caching: Use Laravel’s config caching (php artisan config:cache) to optimize performance for production.
  • Environment Variables: Store sensitive configs (e.g., API keys) in .env and reference them in the config file:
    'services' => [
        'stripe' => [
            'base_uri' => env('STRIPE_API_URL'),
            'auth'     => ['username' => env('STRIPE_KEY'), 'password' => ''],
        ],
    ],
    

Advanced Customization

  • Custom Handler Stacks: Extend the factory to support custom middleware or plugins:

    GuzzleFactory::extend('custom', function ($config) {
        $stack = HandlerStack::create();
        $stack->push(new CustomMiddleware());
        return new GuzzleHttp\Client($config + ['handler' => $stack]);
    });
    

    Use the extended factory:

    $client = GuzzleFactory::make(['base_uri' => 'https://example.com'], null, null, 'custom');
    
  • Retry Configuration: Customize retry logic via the config file:

    'guzzle-factory' => [
        'defaults' => [
            'timeout' => 10,
            'retries' => [
                'max_retries' => 3,
                'retry_delay' => 100,
                'except' => [401, 403],
            ],
        ],
    ],
    

Gotchas and Tips

Pitfalls and Debugging

  1. Handler Stack Misconfiguration

    • Issue: Custom middleware not working as expected.
    • Debug Tip: Verify the closure order in the handler stack. Middleware pushed later executes first.
    • Fix:
      $stack->push(Middleware::class, 'name'); // Named middleware for clarity
      
  2. Transport Sharing Overhead

    • Issue: Unexpected performance degradation with transport sharing.
    • Debug Tip: Use TransportSharing::HANDLER_PREFER sparingly—it’s best-effort and may not always improve performance.
    • Fix: Disable sharing for low-frequency clients:
      $client = GuzzleFactory::make(['base_uri' => 'https://example.com']); // Default: no sharing
      
  3. TLS/SSL Errors

    • Issue: Clients fail with SSL errors despite correct verify settings.
    • Debug Tip: Ensure the config enforces TLS 1.2+ (default in v7.0+):
      'guzzle-factory' => [
          'defaults' => [
              'verify' => true, // Always verify unless testing
              'curl' => [
                  CURLOPT_SSL_VERSION => CURL_SSL_VERS_TLSv1_2,
              ],
          ],
      ],
      
    • Fix: Update PHP’s openssl extension or use a custom CA bundle:
      $client = GuzzleFactory::make([
          'base_uri' => 'https://example.com',
          'verify' => '/path/to/custom/ca-bundle.crt',
      ]);
      
  4. Config Overrides

    • Issue: Config values not being applied.
    • Debug Tip: Check the config file location (config/guzzle-factory.php) and ensure it’s published.
    • Fix: Publish and merge configs explicitly:
      php artisan vendor:publish --provider="GrahamCampbell\GuzzleFactory\GuzzleFactoryServiceProvider" --tag="config"
      
  5. Dependency Injection Conflicts

    • Issue: Laravel’s Http facade or other Guzzle instances causing conflicts.
    • Debug Tip: Use explicit bindings to avoid ambiguity:
      $this->app->bind('custom.guzzle', fn() => GuzzleFactory::make([]));
      
    • Fix: Avoid mixing Http facade and GuzzleFactory for the same API.

Extension Points

  1. Custom Factory Extensions

    • Use Case: Add domain-specific client configurations (e.g., stripe, paypal).
    • Example:
      GuzzleFactory::extend('stripe', function ($config) {
          return GuzzleFactory::make(
              $config + ['auth' => ['username' => env('STRIPE_KEY'), 'password' => '']]
          );
      });
      
    • Usage:
      $stripe = GuzzleFactory::make([], null, null, 'stripe');
      
  2. Dynamic Config Loading

    • Use Case: Load configs from a database or external service.
    • Example:
      $config = Cache::remember('api_config', 60, function () {
          return ApiConfig::where('name', 'stripe')->first()->toArray();
      });
      $client = GuzzleFactory::make($config);
      
  3. **Event-D

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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai