El cliente HTTP de Laravel es una API sencilla que envuelve a Guzzle.
A través del facade Http puedes escribir con concisión peticiones HTTP a servicios y APIs externas.
use Illuminate\Support\Facades\Http;$response = Http::get('https://api.example.com/users');
Guzzle viene preinstalado, así que puedes empezar a usar el cliente sin configuración adicional.
Métodos como Http::get() devuelven una instancia de Illuminate\Http\Client\Response.
El objeto ofrece numerosos métodos para inspeccionar la respuesta.
$response = Http::get('https://api.example.com/users/1');// Cuerpo de la respuesta$response->body(); // Como cadena$response->json(); // Convertido en array$response->json('name'); // Una clave concreta$response->object(); // Como objeto stdClass$response->collect(); // Como Collection// Estado$response->status(); // Código HTTP (p. ej. 200)$response->successful(); // true si es 2xx$response->failed(); // true si es 4xx o 5xx$response->clientError(); // true si es 4xx$response->serverError(); // true si es 5xx// Códigos habituales$response->ok(); // 200$response->created(); // 201$response->noContent(); // 204$response->notFound(); // 404$response->unauthorized(); // 401$response->forbidden(); // 403$response->unprocessableEntity(); // 422$response->tooManyRequests(); // 429
Las respuestas JSON también son accesibles como array.
// Timeout de respuesta (por defecto 30 s)$response = Http::timeout(10)->get('https://api.example.com/slow-endpoint');// Timeout de conexión (por defecto 10 s)$response = Http::connectTimeout(5)->get('https://api.example.com/endpoint');
Si se supera el timeout se lanza Illuminate\Http\Client\ConnectionException.
Es recomendable configurar siempre un timeout en las llamadas a APIs externas.
Con throw() se lanza Illuminate\Http\Client\RequestException cuando hay errores.
// Lanza excepción si la respuesta es 4xx/5xx$response = Http::post('https://api.example.com/users', $data)->throw();// throwIf(): lanza excepción cuando la condición es true (ejemplo independiente)$response = Http::get('https://api.example.com/users/1');$response->throwIf($response->status() === 422);// throwUnlessStatus(): lanza excepción salvo con el código indicado (ejemplo independiente)$response = Http::post('https://api.example.com/orders', $data);$response->throwUnlessStatus(201);
throw() devuelve la propia respuesta, por lo que se puede encadenar.
En tests usa Http::fake() para simular respuestas sin realizar la petición real.
use Illuminate\Support\Facades\Http;Http::fake();// Todas las peticiones devuelven 200$response = Http::get('https://api.example.com/users');$response->successful(); // true
Con Http::assertSent() puedes validar el contenido de las peticiones enviadas.
use Illuminate\Http\Client\Request;use Illuminate\Support\Facades\Http;Http::fake();Http::withToken('my-token')->post('https://api.example.com/users', [ 'name' => 'Ana García',]);Http::assertSent(function (Request $request) { return $request->url() === 'https://api.example.com/users' && $request->hasHeader('Authorization', 'Bearer my-token') && $request['name'] === 'Ana García';});// Comprobar que no se ha enviadoHttp::assertNotSent(function (Request $request) { return $request->url() === 'https://api.example.com/admin';});// Comprobar que se ha enviado exactamente una peticiónHttp::assertSentCount(1);
En los tests, invoca siempre Http::fake() al principio.
Si te lo saltas, las peticiones irán a las APIs reales.
Con Http::preventStrayRequests() puedes hacer que las peticiones a URLs no simuladas lancen una excepción.
<?phpnamespace App\Http\Controllers;use App\Services\GitHubService;use Illuminate\Http\Client\RequestException;use Illuminate\Http\Client\ConnectionException;use Illuminate\Http\JsonResponse;class GitHubController extends Controller{ public function __construct( private readonly GitHubService $github, ) {} public function show(string $username): JsonResponse { try { $user = $this->github->getUser($username); return response()->json($user); } catch (ConnectionException) { return response()->json(['error' => 'No se ha podido conectar con la API de GitHub.'], 503); } catch (RequestException $e) { $status = $e->response->status(); if ($status === 404) { return response()->json(['error' => 'Usuario no encontrado.'], 404); } return response()->json(['error' => 'Se ha producido un error en la API de GitHub.'], 502); } }}