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

guzzle/guzzle

Guzzle 3.x is a PHP HTTP client and web service framework with a cURL-like API, persistent connections, pooling, parallel requests, service descriptions, and a Symfony2 event/plugin system. End-of-life; use Guzzle 5+ for maintenance.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require guzzlehttp/guzzle
    
    • Guzzle is auto-discoverable in Laravel via service providers.
  2. First Request

    use GuzzleHttp\Client;
    
    $client = new Client();
    $response = $client->get('https://api.example.com/data');
    $body = $response->getBody()->getContents();
    
  3. Laravel Integration

    • Bind Guzzle to the container in config/app.php (if not auto-discovered):
      'providers' => [
          GuzzleHttp\GuzzleServiceProvider::class,
      ],
      
    • Inject via constructor:
      public function __construct(private Client $client) {}
      

First Use Case: Fetching External Data

// In a Laravel controller/service
$response = $this->client->request('GET', 'https://api.github.com/users/octocat');
$status = $response->getStatusCode();
$json = json_decode($response->getBody(), true);

Implementation Patterns

Common Workflows

1. Request Configuration

  • Base URI & Default Options (Laravel config/services.php):
    'guzzle' => [
        'timeout' => 10.0,
        'base_uri' => env('API_BASE_URL', 'https://api.example.com'),
        'headers' => [
            'Accept' => 'application/json',
            'Authorization' => 'Bearer ' . env('API_TOKEN'),
        ],
    ],
    
  • Bind to container in AppServiceProvider:
    $this->app->singleton(Client::class, function ($app) {
        return new Client($app['config']['services.guzzle']);
    });
    

2. Async Requests

use GuzzleHttp\Promise\Utils;

$promises = [
    $this->client->getAsync('https://api1.example.com/data'),
    $this->client->postAsync('https://api2.example.com/data', ['json' => [...]]),
];

Utils::settle($promises)->wait();

3. Middleware Stack

  • Add logging middleware:
    $stack = HandlerStack::create();
    $stack->push(Middleware::tap(function ($request) {
        Log::debug('Request:', ['url' => $request->getUri()]);
    }));
    
    $client = new Client(['handler' => $stack]);
    

4. Retry Mechanism

  • Use GuzzleHttp\Middleware for retries:
    use GuzzleHttp\Middleware;
    
    $retryMiddleware = Middleware::retry(
        function ($retries, $request, $exception) {
            return $retries < 3 && in_array($exception->getCode(), [429, 500, 502, 503, 504]);
        },
        function ($retries) {
            return 100 * $retries; // Exponential backoff
        }
    );
    

5. Streaming Large Responses

$response = $this->client->get('https://example.com/large-file.zip');
file_put_contents('download.zip', $response->getBody());

6. Laravel HTTP Client Wrapper

  • Extend Laravel’s Http facade for consistency:
    // app/Extensions/HttpClient.php
    namespace App\Extensions;
    
    use GuzzleHttp\Client;
    use Illuminate\Support\Facades\Http;
    
    class HttpClient extends Client {
        public function laravelRequest(string $method, string $url, array $options = []) {
            return Http::withOptions($options)->{$method}($url);
        }
    }
    

Integration Tips

1. API Clients

  • Create dedicated API clients (e.g., StripeClient, GitHubClient) with typed methods:
    class GitHubClient {
        public function __construct(private Client $client) {}
    
        public function getUser(string $username): array {
            $response = $this->client->get("https://api.github.com/users/{$username}");
            return json_decode($response->getBody(), true);
        }
    }
    

2. Event Dispatching

  • Trigger Laravel events on request/response:
    $stack = HandlerStack::create();
    $stack->push(Middleware::tap(function ($request) {
        event(new RequestSent($request));
    }));
    $stack->push(Middleware::tap(function ($response) {
        event(new ResponseReceived($response));
    }));
    

3. Caching Responses

  • Cache API responses with Laravel’s cache:
    $cacheKey = "api_data_{$url}";
    $data = cache()->remember($cacheKey, now()->addHours(1), function () use ($client, $url) {
        return $client->get($url)->json();
    });
    

4. Testing

  • Mock Guzzle in PHPUnit:
    $mock = $this->getMockBuilder(Client::class)
        ->disableOriginalConstructor()
        ->onlyMethods(['get'])
        ->getMock();
    
    $mock->method('get')->willReturn((new MockResponse('{"data": "test"}'));
    
    $this->app->instance(Client::class, $mock);
    

Gotchas and Tips

Pitfalls

1. Connection Pooling

  • Guzzle reuses HTTP connections by default. In Laravel, ensure the Client instance is singleton to avoid connection leaks:
    // Bad: Creates a new client per request (leaks connections)
    $client = new Client();
    
    // Good: Singleton in container
    $this->app->singleton(Client::class, function () {
        return new Client(['timeout' => 10]);
    });
    

2. JSON Encoding/Decoding

  • Guzzle returns raw responses. Always decode JSON manually:
    // Wrong: Assumes JSON (throws exception if not JSON)
    $data = $response->getBody();
    
    // Right:
    $data = json_decode($response->getBody(), true);
    

3. Timeouts

  • Default timeout is no timeout. Always set explicit timeouts:
    $client = new Client(['timeout' => 5.0]); // 5 seconds
    

4. SSL Certificate Issues

  • Disable SSL verification only for testing (never in production):
    $client = new Client(['verify' => false]); // UNSAFE!
    
  • For self-signed certs, use:
    $client = new Client(['verify' => '/path/to/cert.pem']);
    

5. Async Race Conditions

  • Async requests (getAsync) return PromiseInterface. Always handle with wait() or then():
    // Bad: Unhandled promise
    $this->client->getAsync('...');
    
    // Good:
    $promise = $this->client->getAsync('...');
    $promise->then(function ($response) { /* ... */ });
    

6. Laravel Cache vs. Guzzle Cache

  • Guzzle’s built-in caching (CacheMiddleware) conflicts with Laravel’s cache. Avoid mixing them.

Debugging Tips

1. Enable Debugging

  • Add debug middleware:
    $stack->push(Middleware::tap(function ($request, $response) {
        if ($response->getStatusCode() >= 400) {
            Log::error('API Error', [
                'url' => $request->getUri(),
                'status' => $response->getStatusCode(),
                'body' => (string) $response->getBody(),
            ]);
        }
    }));
    

2. Log Requests/Responses

  • Use GuzzleHttp\HandlerStack to log:
    $stack->push(Middleware::tap(function ($request) {
        Log::debug('Request', [
            'url' => (string) $request->getUri(),
            'headers' => $request->getHeaders(),
            'body' => $request->getBody() ? $request->getBody()->getContents() : null,
        ]);
    }));
    

3. Handle Redirects

  • Disable redirects if unexpected:
    $client = new Client(['allow_redirects' => false]);
    
  • Check response->getHeader('Location') for redirect URLs.

4. Proxy Support

  • Configure proxies in Laravel .env:
    GUZZLE_PROXY=http://proxy.example.com:8080
    
  • Pass to client:
    $client = new Client(['proxy' => env('GUZZLE_PROXY')]);
    

Extension Points

1. Custom Handlers

  • Implement GuzzleHttp\Promise\PromiseInterface for custom logic:
    $handler = new CustomHandler();
    $client = new Client
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui