doganddev
Accueil Blog Boutique

Laravel : requêtes HTTP concurrentes avec Http::pool et Http::batch

DOG&DEV · 25/01/2025

Mises à Jour Réseaux
Laravel : requêtes HTTP concurrentes avec Http::pool et Http::batch

Laravel : requêtes HTTP concurrentes avec Http::pool et Http::batch

Lorsqu’une page ou un job doit appeler plusieurs APIs (Stripe, météo, CRM, etc.), les requêtes séquentielles s’additionnent et dégradent le temps de réponse. Le HTTP Client Laravel fournit Http::pool et Http::batch pour exécuter ces appels en parallèle. Ce guide présente la syntaxe, les callbacks (before, progress, catch, finally) et la gestion des timeouts et erreurs.

Prérequis

  • Laravel 10+ (ou 11/12) avec Guzzle (inclus dans le HTTP Client)
  • Plusieurs URLs ou endpoints à appeler dans la même logique

1. Http::pool — requêtes parallèles simples

Http::pool envoie plusieurs requêtes en même temps et renvoie un tableau de réponses indexé par les clés fournies avec as('key').

Exemple : tableau de bord multi-sources

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']->successful()) {
    $githubData = $responses['github']->json();
}

$weather = $responses['weather']->successful()
    ? $responses['weather']->json()
    : ['temp' => 'N/A'];

Chaque requête peut avoir ses headers, tokens, options. Le pool attend la fin de toutes les requêtes avant de retourner.

2. Http::batch — callbacks et suivi

Http::batch ajoute des callbacks : before, progress (après chaque réponse), catch (en cas d’erreur réseau/timeout), finally.

Exemple : synchronisation multi-plateformes

use Illuminate\Http\Client\Batch;
use Illuminate\Support\Facades\Http;

$product = ['name' => 'T-Shirt Laravel', 'price' => 29.99];

$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("Début sync pour {$batch->totalRequests} plateformes."))
->progress(fn (Batch $batch, $key, $response) => $response->successful()
    ? logger()->info("Sync OK : {$key}")
    : logger()->warning("Sync échec : {$key}"))
->catch(fn (Batch $batch, $key, $error) => logger()->error("Erreur {$key} : " . $error->getMessage()))
->finally(fn (Batch $batch) => logger()->info("Sync terminée."))
->send();

catch est appelé pour les exceptions (timeout, connexion refusée, etc.) ; les autres requêtes du batch continuent. progress reçoit la réponse (objet Response) pour chaque requête terminée.

3. Timeouts

Un seul appel lent peut retarder tout le pool/batch. Toujours définir un timeout sur les requêtes sensibles :

$pool->as('slow_api')->timeout(2)->get('https://slow.service/data');

Même principe dans Http::batch : $batch->as('key')->timeout(3)->get(...).

4. Gestion des erreurs

  • Dans un pool : les réponses sont toujours dans le tableau ; une requête en échec donne une Response avec $response->successful() === false ou une exception selon la config. Vérifier $responses['key']->successful() avant d’utiliser le corps.
  • Dans un batch : catch reçoit les exceptions (réseau, timeout) ; pour les 4xx/5xx, c’est dans progress avec une Response non successful. Adapter la logique (retry, fallback, log) selon le besoin.

Dépannage

Symptôme Cause possible Correctif
Pool très lent Une requête sans timeout bloque Ajouter ->timeout(n) sur les requêtes lentes ou peu fiables
catch non appelé pour un 500 catch ne reçoit que les exceptions (réseau, timeout) Traiter les 4xx/5xx dans progress via $response->successful()
Clé manquante dans $responses Faute de frappe dans as('key') Vérifier que les clés correspondent à celles utilisées à la réception

Bonnes pratiques

  • Nommer les requêtes avec as('key') pour un code lisible et un accès direct.
  • Timeouts systématiques sur les APIs externes.
  • catch et progress pour logger et monitorer ; finally pour le nettoyage ou les notifications de fin.

Ressources


Cet article s’inscrit dans notre série de guides technique et développement web. Pour un serveur ou une application sur-mesure, contact.

Commentaires (0)

Laisser un commentaire