В современных веб-приложениях почти всегда есть потребность общаться с внешними сервисами, будь то Stripe для платежей, OpenAI для обработки данных или CRM-система. Проблема в том, что традиционный последовательный HTTP-вызов тормозит работу: если нужно выполнить три API-запроса по одному, и каждый занимает 1 секунду, пользователь ждёт ~3 секунды. В продакшене такого ожидания проще избегать.
К счастью, Laravel предлагает инструменты для конкурентных запросов к API, позволяя отправлять сразу несколько запросов параллельно и значительно сокращать общее время ответа. Разберём главные подходы, Http::pool и Http::batch, с примерами и рекомендациями.
Предположим, ваш дашборд должен получить данные из трёх систем:
GitHub
Погодного API
Внутренней статистики
Если отправлять запросы по очереди, общее время зависит от суммы всех задержек. С Http::pool они стартуют одновременно, и общее время ≈ длительность самого медленного запроса. Это даёт колоссальный выигрыш в производительности, особенно при медленных API.
1. Http::pool - быстрый параллельный пул запросов
Метод Http::pool() позволяет объединить несколько HTTP-запросов в один "пул" и выполнить их параллельно. Это удобно, когда нужно получить данные из нескольких источников без сложной логики обработки прогресса.
Пример: параллельный GET-запрос
use Illuminate\Http\Client\Pool;
use Illuminate\Support\Facades\Http;
$responses = Http::pool(fn (Pool $pool) => [
$pool->as('github')->get('https://api.github.com/users/laravel'),
$pool->as('weather')->get('https://api.weather.com/v3/today'),
$pool->as('stats')->withToken('secret-key')->get('https://internal.metrics/v1/usage'),
]);Как работать с ответами
if ($responses['github']->ok()) {
$githubData = $responses['github']->json();
}
// Обработка ответа с проверкой успеха
$weather = $responses['weather']->successful()
? $responses['weather']->json()
: ['temp' => 'N/A'];Почему это удобно:
Named keys (
as('github')) позволяют обращаться к ответам по ключам, а не по индексам массива.Можно гибко настраивать каждую часть запроса (заголовки, токены).
Запросы выполняются одновременно.
2. Http::batch - продвинутый пакетный пул с колбэками
Если вы хотите не только отправлять набор запросов, но и отслеживать их прогресс, обрабатывать ошибки или логировать события, стоит использовать Http::batch(). Этот метод дает больше контроля над жизненным циклом запросов.
Пример: синхронизация продуктов
use Illuminate\Http\Client\Batch;
use Illuminate\Support\Facades\Http;
$responses = Http::batch(function (Batch $batch) use ($product) {
return [
$batch->as('shopify')->post('https://shopify.com/api/products', $product),
$batch->as('amazon')->post('https://amazon.com/api/listing', $product),
$batch->as('ebay')->post('https://ebay.com/api/items', $product),
];
})
->before(fn (Batch $batch) => logger()->info("Starting sync for {$batch->totalRequests} platforms."))
->progress(fn (Batch $batch, $key, $response) => logger()->info("Synced to: {$key}"))
->catch(fn (Batch $batch, $key, $error) => logger()->error("Error at {$key}: {$error->getMessage()}"))
->finally(fn () => logger()->info("Sync complete."))
->send();Что дают колбэки
before() - логика перед отправкой всех запросов.
progress() - отслеживает результат каждого отдельного запроса по мере завершения.
catch() - ловит ошибки на уровне конкретных запросов.
finally() - выполняется после завершения всего набора.
3. Обработка ошибок и таймаутов
При параллельных запросах важно учитывать задержки и возможные "зависания" внешних API. Если один из сервисов долго отвечает, он может задержать весь пул.
Совет: всегда настраивайте таймауты для каждого запроса:
$pool->as('slow_api')->timeout(2)->get('https://slow.service/data');Такой подход защитит ваш код от длительных зависаний и сделает поведение более предсказуемым.
Использование Http::pool и Http::batch в Laravel позволяет избавиться от узких мест, связанных с последовательными API-запросами. Переход от последовательного выполнения к параллельному даёт ощутимое повышение скорости и отзывчивости приложений при интеграции с внешними сервисами.