โ† Semua pembelajaran / Laravel Nol โ†’ Enterprise
Fase 5 ยท API & Frontend

HTTP client

Setiap panggilan ke layanan luar adalah titik kegagalan yang bisa menyeret aplikasimu ikut mati. Klien HTTP Laravel membuat pengaman untuk itu jadi satu baris, bukan satu proyek.

Sumber asli laravel.com Resmi Rangkuman ~6 menit baca

Intisari

  • Selalu setel timeout. Tanpa itu, layanan luar yang menggantung akan menahan worker-mu.
  • retry() dengan jeda menaik untuk kegagalan sementara.
  • Respons tidak melempar exception secara default โ€” panggil throw() atau periksa failed().
  • Http::fake() membuat tes berjalan tanpa jaringan sama sekali.
  • Panggilan luar di dalam siklus permintaan sebaiknya dipindahkan ke antrean.

Bentuk yang layak dipakai di produksi

use Illuminate\Support\Facades\Http;

$respons = Http::withToken(config('services.mitra.token'))
    ->timeout(5)                 // batas total
    ->connectTimeout(2)          // batas membangun koneksi
    ->retry(3, 200, throw: false)
    ->acceptJson()
    ->get('https://api.mitra.test/artikel', ['halaman' => 1]);

if ($respons->failed()) {
    Log::warning('mitra gagal', ['status' => $respons->status()]);

    return null;
}

$data = $respons->json('data');

Timeout adalah setelan terpenting di halaman ini. Tanpa itu, satu layanan luar yang lambat akan menahan proses PHP-mu tanpa batas. Sepuluh permintaan seperti itu berarti sepuluh worker terpakai; seratus, dan seluruh aplikasi berhenti merespons โ€” padahal kodemu sendiri baik-baik saja. Angka yang sehat: total lebih pendek daripada timeout permintaan HTTP-mu sendiri, dan jauh lebih pendek daripada kesabaran pengguna.

Retry yang tidak memperburuk keadaan

Http::retry(
    times: 3,
    sleepMilliseconds: fn (int $percobaan) => $percobaan * 200,   // 200, 400, 600
    when: fn (Throwable $e, $req) => $e instanceof ConnectionException,
)->post($url, $data);
KondisiBoleh diulang?
Timeout koneksi, 502, 503, 504Ya โ€” kemungkinan besar sementara
429 Too Many RequestsYa, tapi tunggu sesuai Retry-After
400, 422 (permintaanmu salah)Tidak โ€” mengulang menghasilkan hasil yang sama
401, 403Tidak โ€” masalah kredensial
POST yang tidak idempotenHati-hati โ€” bisa jadi tagihan dobel

Mengulang POST itu berbahaya. Kalau permintaan pertama sebenarnya sampai dan diproses, tapi responsnya yang hilang, percobaan kedua akan membuat pesanan atau tagihan kedua. Untuk operasi yang mengubah keadaan, kirim kunci idempotensi yang dikenali penyedia โ€” atau jangan ulangi sama sekali.

Klien yang punya nama

// AppServiceProvider::boot()
Http::macro('mitra', fn () => Http::baseUrl(config('services.mitra.url'))
    ->withToken(config('services.mitra.token'))
    ->timeout(5)
    ->retry(3, 200)
    ->acceptJson());
Http::mitra()->get('/artikel');
Http::mitra()->post('/artikel', $data);

Manfaatnya: setelan timeout dan retry ditulis sekali. Tidak ada lagi satu pemanggilan yang lupa timeout karena ditulis buru-buru pada hari Jumat sore.

Menguji tanpa jaringan

Http::fake([
    'api.mitra.test/artikel*' => Http::response(['data' => [['id' => 1]]], 200),
    'api.lain.test/*'         => Http::response(null, 500),
    '*'                       => Http::response('tidak terduga', 404),
]);

$this->get('/impor');

Http::assertSent(fn ($req) =>
    $req->hasHeader('Authorization') && $req->url() === 'https://api.mitra.test/artikel?halaman=1');

// Urutan respons: gagal dulu, lalu berhasil โ€” untuk menguji jalur retry
Http::fakeSequence()
    ->push(null, 500)
    ->push(['data' => []], 200);

Tambahkan Http::preventStrayRequests() di TestCase-mu. Dengan itu, setiap panggilan HTTP yang tidak di-fake akan menggagalkan tes alih-alih diam-diam menghubungi internet. Tanpa itu, suite tes bisa mengirim permintaan sungguhan ke penyedia โ€” lambat, tidak stabil, dan sesekali benar-benar memicu efek samping di dunia nyata.

Panggilan bersamaan

$hasil = Http::pool(fn (Pool $pool) => [
    $pool->as('cuaca')->get('https://api.cuaca.test/hari-ini'),
    $pool->as('kurs')->get('https://api.kurs.test/idr'),
    $pool->as('bursa')->get('https://api.bursa.test/ihsg'),
]);

$cuaca = $hasil['cuaca']->json();

Tiga panggilan berurutan yang masing-masing 300 ms memakan 900 ms; dijalankan bersamaan, sekitar 300 ms. Untuk halaman yang menggabungkan beberapa sumber, ini perbedaan yang langsung terasa.

Aturan yang menyelamatkan produksi

  1. Selalu timeout. Tidak ada pengecualian.
  2. Panggilan yang tidak dibutuhkan untuk merender halaman pindahkan ke antrean.
  3. Cache respons yang jarang berubah โ€” sekaligus melindungimu dari rate limit penyedia.
  4. Jangan pernah mencatat isi respons mentah tanpa disaring; di dalamnya sering ada token dan data pribadi.
  5. Sediakan perilaku cadangan saat penyedia mati: nilai terakhir yang di-cache, atau bagian halaman yang dihilangkan โ€” bukan halaman 500.

Latihan: buat macro Http::mitra() dengan timeout 3 detik dan retry 2 kali, panggil URL yang sengaja lambat (https://httpbin.org/delay/10), dan pastikan aplikasimu menyerah setelah 3 detik. Lalu tulis tesnya dengan Http::fakeSequence() yang gagal sekali lalu berhasil.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.