La función `retry` de Laravel
A veces, especialmente al interactuar con APIs externas, nuestro código puede parecer no determinista. A veces funciona, y a veces no 🤦♀️.
En muchos casos, simplemente reintentar la llamada puede hacer que vuelva a funcionar (tal vez la API tenía mucha carga en ese momento o nos pasamos el límite de llamadas por segundo).
Afortunadamente para nosotros, Laravel tiene una función súper útil llamada retry
. Teniendo el siguiente código:
foreach ($products as $product) {
$response = Http::get('https://my-api.com/get-price', ['id' => $product->id])->throw()->json();
$product->price = $response['price'];
}
Este código parece correcto y funcional pero, ¿qué pasa si my-api.com
está temporalmente no disponible o con mucha carga? Para controlar mejor la situación podríamos usar la función retry
, que reintentaría la llamada HTTP en caso de fallo. Tiene la siguiente estructura:
function retry(int $times, Callback $callback, int $delayInMs);
Por lo que podemos llamarla así:
foreach ($products as $product) {
$response = retry(3, fn () => Http::get('https://my-api.com/get-price', ['id' => $product->id])->throw()->json(), 5000);
$product->price = $response['price'];
}
En este caso, intentaríamos hacer la llamada API y, si se lanza una excepción (con el →throw()
), lo reintentaría hasta 2 veces más esperando 5 segundos antes de cada reintento.
De hecho, es tan común usar esta función con las llamadas API que la clase Http
ya la tiene directamente implementada:
foreach ($products as $product) {
$response = Http::retry(3, 5000)->get('https://my-api.com/get-price', ['id' => $product->id])->throw()->json();
$product->price = $response['price'];
}