Laravel HTTP Client: Guzzle Replacement
Laravel HTTP Client: Guzzle Replacement
Laravel HTTP Client: Guzzle Replacement
Tip: Simple GET Request
$response = Http::get('https://api.example.com/users');
$data = $response->json();
No need to configure Guzzle manually.
Gotcha: Exceptions Are Not Thrown by Default
$response = Http::get('https://api.example.com/missing');
$response->throw();
Tip: Retry on Failure
Http::retry(3, 100)->get('https://api.example.com/data');
Retries 3 times with 100ms delay between attempts.
Gotcha: Timeout Defaults to 30 Seconds
Http::timeout(5)->get('https://slow-api.com');
Set explicit timeouts for slow APIs.
Tip: Fake HTTP Responses for Testing
Http::fake([
'api.example.com/*' => Http::response(['id' => 1], 200),
]);
No real HTTP calls during tests.
Gotcha: Pool for Concurrent Requests
$responses = Http::pool(fn($pool) => [
$pool->get('https://api.example.com/users'),
$pool->get('https://api.example.com/posts'),
]);
Runs requests in parallel.
Tip: Use route:cache Carefully
php artisan route:cache is fast, but it doesn't work with closure-based routes. Every time you cache routes, Laravel serializes them. If you have Route::redirect() or closure callbacks, the cache breaks. Stick to controller-based routes in production.
Tip: Model APP_KEY Rotation
Rotating APP_KEY invalidates all encrypted data — cookies, encrypted DB columns, and password reset tokens. If you must rotate (e.g., after a leak), plan a migration that re-encrypts existing data with the new key.
Gotcha: Local Scope Leaks
Global scopes defined in booted() apply to ALL queries on that model — including relationships. An innocent User::all() in admin panel might exclude soft-deleted users if a global scope is active.
Senior Insight
The HTTP client wrapper in Laravel is excellent, but I've seen teams forget to configure timeouts and retries, leading to cascading failures when an external API is slow. My standard setup: always set a connect timeout of 3 seconds and a total timeout of 15 seconds, implement exponential backoff retries for idempotent requests, and use Http::fake() in tests to simulate failure modes. An untested HTTP integration is not an integration — it's a future incident.
Source: Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/laravel), Spatie Blog (https://spatie.be/blog)