Request terkirim bukan akhir cerita — justru di response-lah keputusan diambil. Apakah panggilan berhasil? Data ada di key mana? Berapa sisa kuota di header rate limit? Dan yang paling rawan kesalahan: bagaimana reaksi kita saat status bukan 2xx. Tanpa kebiasaan yang rapi, kode client dipenuhi if ($response->status() === 200) yang rapuh — 201 dan 204 pun sukses. Object Illuminate\Http\Client\Response menyediakan perangkat lengkap untuk membaca dan mengevaluasi response, dan chapter ini mengeksplorasinya satu per satu sampai pola penanganan error yang siap produksi.
Membaca Status dan Header #
Empat method pemeriksaan menutup hampir semua kebutuhan: status() mengembalikan kode HTTP, sementara successful(), failed(), dan ok() mengevaluasi kelompok status:
<?php
use Illuminate\Support\Facades\Http;
Http::fake([
'api.example.com/artikel' => Http::response([
'data' => [
['id' => 1, 'judul' => 'Belajar HTTP Client', 'tag' => ['laravel', 'http']],
['id' => 2, 'judul' => 'Belajar Response', 'tag' => ['laravel', 'api']],
],
'meta' => ['total' => 2],
], 200, ['X-RateLimit-Remaining' => '57']),
]);
$response = Http::get('https://api.example.com/artikel');
echo 'status: '.$response->status()."\n";
echo 'successful: '.var_export($response->successful(), true)."\n";
echo 'failed: '.var_export($response->failed(), true)."\n";
echo 'ok: '.var_export($response->ok(), true)."\n";
echo 'X-RateLimit-Remaining: '.$response->header('X-RateLimit-Remaining')."\n";Output yang Dihasilkan:
status: 200
successful: true
failed: false
ok: true
X-RateLimit-Remaining: 57Perbedaannya presisi: successful() benar untuk semua status 2xx, ok() khusus 200, dan failed() menutup rentang 4xx–5xx. Method header($nama) membaca satu header response tanpa pusing soal case-sensitivity.
Membaca Body: json, body, collect, object #
Empat pintu menuju isi response, sesuai selera pengolahan kita. Method json() menerima key path bergaya dot sehingga array bersarang bisa diambil langsung tanpa rantai indeks:
<?php
// ... $response dari Http::get('https://api.example.com/artikel') di atas
echo 'data.0.judul: '.$response->json('data.0.judul')."\n";
echo 'meta.total: '.$response->json('meta.total')."\n";
echo 'data.0.tag.1: '.$response->json('data.0.tag.1')."\n";
echo 'tidak-ada (dengan default): '
.var_export($response->json('meta.habis', 'belum ada'), true)."\n";
echo 'body: '.substr($response->body(), 0, 60)."...\n";Output yang Dihasilkan:
data.0.judul: Belajar HTTP Client
meta.total: 2
data.0.tag.1: http
tidak-ada (dengan default): 'belum ada'
body: {"data":[{"id":1,"judul":"Belajar HTTP Client","tag":["larav...Key yang tidak ada menghasilkan null — atau nilai default pada parameter kedua, seperti 'belum ada' di atas. Sementara body() mengembalikan string mentah apa adanya untuk response non-JSON.
Dua method sisanya memberi bentuk yang lebih nyaman. collect() mengubah bagian response menjadi Illuminate\Support\Collection, membuka seluruh perangkat collection: pluck, flatten, sum, sampai filter:
<?php
$judul = $response->collect('data')->pluck('judul');
echo 'class: '.get_class($judul)."\n";
echo 'judul: '.$judul->implode(', ')."\n";
$tagUnik = $response->collect('data')->pluck('tag')->flatten()->unique()->values();
echo 'tag unik: '.$tagUnik->implode(', ')."\n";Output yang Dihasilkan:
class: Illuminate\Support\Collection
judul: Belajar HTTP Client, Belajar Response
tag unik: laravel, http, apiTerakhir, object() mem-parse JSON menjadi object PHP biasa — nyaman untuk akses property berantai:
<?php
$obj = $response->object();
echo 'meta->total: '.$obj->meta->total."\n";
echo 'data[0]->judul: '.$obj->data[0]->judul."\n";Output yang Dihasilkan:
meta->total: 2
data[0]->judul: Belajar HTTP Clientthrow dan Keluarganya #
Masalah dengan memeriksa failed() manual adalah kelalaian: satu cabang if yang terlewat, dan response gagal mengalir ke kode seolah sukses. Method throw() membalik pendekatannya — response sukses lewat begitu saja, response gagal melempar RequestException seketika:
<?php
use Illuminate\Support\Facades\Http;
Http::fake([
'api.example.com/artikel' => Http::response(['pesan' => 'kuota habis'], 429),
]);
try {
Http::get('https://api.example.com/artikel')->throw();
} catch (Illuminate\Http\Client\RequestException $e) {
echo 'terlempar: '.get_class($e)."\n";
echo 'pesan exception: '.$e->getMessage()."\n";
echo 'status via exception: '.$e->response->status()."\n";
}Output yang Dihasilkan:
terlempar: Illuminate\Http\Client\RequestException
pesan exception: HTTP request returned status code 429:
{"pesan":"kuota habis"}
status via exception: 429Perhatikan bahwa RequestException menyimpan response asli di property $e->response — pesan error, header, dan body tetap bisa dibaca lengkap dari dalam catch. Keluarga throw() menambah dua variasi: throwIf($kondisi) hanya melempar bila kondisi benar, dan throw() dengan callback yang berjalan tepat sebelum exception dilempar — tempat ideal mencatat log:
<?php
Http::fake(['api.example.com/cepat' => Http::response(['pesan' => 'oke'], 200)]);
$response = Http::get('https://api.example.com/cepat')->throwIf(false);
echo 'throwIf(false) status: '.$response->status()."\n";Output yang Dihasilkan:
throwIf(false) status: 200Untuk alur tanpa exception sama sekali, onError() menerima callback yang dijalankan hanya saat response gagal — response tetap dikembalikan untuk diproses manual:
<?php
Http::fake(['api.example.com/cepat' => Http::response(['pesan' => 'oke'], 200)]);
$pesan = 'belum terjadi apa-apa';
Http::get('https://api.example.com/cepat')->onError(function ($response) use (&$pesan) {
$pesan = 'error '.$response->status();
});
echo 'pesan: '.$pesan."\n";Output yang Dihasilkan:
pesan: belum terjadi apa-apaCallback onError tidak pernah dijalankan karena response sukses — variabel $pesan tetap bernilai awalnya.
Pola try/catch Lengkap #
Di aplikasi nyata, dua jenis exception berbeda perlu ditangkap terpisah: ConnectionException berarti jaringan atau timeout bermasalah (request mungkin tidak pernah sampai), sedangkan RequestException berarti server menjawab dengan keberatan:
<?php
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
try {
$response = Http::timeout(5)
->retry(2, 100)
->get('https://api.example.com/artikel')
->throw();
echo 'berhasil: '.$response->json('pesan')."\n";
} catch (ConnectionException $e) {
echo 'jaringan bermasalah: '.$e->getMessage()."\n";
} catch (RequestException $e) {
echo 'API menolak: status '.$e->response->status()."\n";
}Output yang Dihasilkan:
API menolak: status 429Membaca satu response sudah kita kuasai. Berikutnya kita naik tingkat: mengonsumsi REST API sungguhan dengan pagination, filter, dan pemetaan ke model Eloquent — praktik lengkapnya di chapter Mengakses REST API . Rujukan semua method response ada di dokumentasi HTTP Client .