Permintaan klien HTTP asinkron datang di Laravel 8.x – Amit Merchant – Blog tentang PHP, JavaScript, dan lainnya

Kembali pada Maret 2020, ketika Laravel 7 dirilis, klien HTTP baru diperkenalkan yang pada dasarnya merupakan pembungkus klien HTTP Guzzle. Ini membuat pengalaman pengembang jauh lebih lancar dan mudah.

Permintaan sinkron

Misalnya, permintaan POST tipikal yang menggunakan klien HTTP akan terlihat seperti ini.

$response = Http::post('http://test.com/users', [
    'name' => 'Steve',
    'role' => 'Network Administrator',
]);

Berbeda dengan era pra-Laravel 7.x di mana Anda perlu menggunakan Guzzle sebagai perpustakaan eksternal seperti itu.

$client = new GuzzleHttpClient();

$request = $client->post('http://test.com/users',  [
    'name' => 'Steve',
    'role' => 'Network Administrator',
]);

$response = $request->send();

Seperti yang Anda ketahui, permintaan yang dibuat menggunakan klien HTTP Laravel 7.x, meskipun menggunakan Guzzle under-the-hood, terlihat lebih ringkas dan elegan.

Semua permintaan yang Anda buat menggunakan klien HTTP ini, bersifat sinkron. Jadi, jika Anda memanggil 5 permintaan eksternal, masing-masing akan dipanggil setelah permintaan selesai sebelum mendapatkan respons. Harus ada semacam sifat asinkron untuk permintaan ini.

Dan ternyata, Guzzle sudah memberikan support untuk permintaan asynchronous berupa Guzzle / Promises.

Ini hanya masalah penerapannya di klien HTTP Laravel.

Dan PR ini mencoba melakukan hal yang sama.

Permintaan asinkron serentak

Seperti yang saya sebutkan sebelumnya, PR ini oleh Andrea Marco Sartori membawa konkurensi saat mengirim permintaan asinkron dengan klien HTTP Laravel dengan menggunakan Guzzle / Promises under-the-hood. PR akan dimasukkan dalam rilis Laravel 8.x.

Pada dasarnya ada dua cara untuk membuat permintaan asinkron menggunakan ini.

  • Permintaan asinkron menggunakan async()
  • Kumpulan untuk menangani beberapa permintaan asinkron secara bersamaan

Permintaan asinkron menggunakan async()

Jika Anda ingin membuat permintaan asinkron, Anda dapat membuatnya seperti itu.

$promise = Http::async()->get($url);

Seperti yang Anda ketahui, Anda perlu merantai async() metode pada klien Http sebelum membuat permintaan. Namun alih-alih membalas, ini akan mengembalikan janji yang bisa Anda selesaikan / tolak.

Lantas, bagaimana tanggapannya? Anda selanjutnya dapat merantai then() metode berdasarkan apakah janji dipenuhi atau ditolak seperti itu.

$promise = Http::async()->get($url)->then(
    fn (Response|TransferException $result) => $this->handleResult($result)
);

Seperti yang Anda ketahui, panggilan balik di file then() metode dapat menerima yang berikut ini berdasarkan status janji.

  • Contoh dari IlluminateHttpClientResponse jika janji itu terpenuhi
  • Contoh dari IlluminateHttpClientResponse jika janji ditolak tetapi tanggapan diberikan (4xx, 5xx kesalahan)
  • Sebuah instance dari GuzzleHttp Exception TransferException jika janji ditolak tanpa respons (mis. Batas waktu)

Dan begitulah cara Anda mendapatkan respons dari permintaan asynchronous.

Kumpulan untuk beberapa permintaan asinkron

Jika Anda ingin membuat beberapa permintaan asinkron pada saat yang sama, Anda dapat menggunakan kumpulan seperti itu.

use IlluminateHttpClientPool;

// the waiting time will be ~6 seconds instead of 12
$responses = Http::pool(fn (Pool $pool) => [
    $pool->get('https://httpbin.org/delay/6')->then(/* ... */),
    $pool->get('https://httpbin.org/delay/3')->then(/* ... */),
    $pool->get('https://httpbin.org/delay/3')->then(/* ... */),
]);

$responses[0]->ok();
$responses[1]->successful();

Karena semua permintaan di kumpulan bersifat asinkron, permintaan paling lambat menentukan waktu tunggu maksimum agar semua janji dipenuhi.

Permintaan asinkron juga dapat ditambahkan ke kumpulan dengan kunci:

$responses = Http::pool(fn (Pool $pool) => [
    $pool->add('foo')->get('https://httpbin.org/delay/6')->then(/* ... */),
    $pool->add('bar')->get('https://httpbin.org/delay/3')->then(/* ... */),
    $pool->add('baz')->get('https://httpbin.org/delay/3')->then(/* ... */),
]);

$responses['foo']->ok();
$responses['bar']->successful();
$connectionFailed = $responses['baz'] instanceof GuzzleHttpExceptionConnectException;

Tanggapan adalah contoh dari IlluminateHttpClientResponse jika permintaan ditanggapi (2xx, 3xx, 4xx, 5xx). Sebaliknya, jika tidak ada tanggapan yang diterima, pengecualian yang memicu penolakan janji akan dikembalikan.

Dalam Penutupan

Dan beginilah cara Anda membuat permintaan asinkron di versi Laravel mendatang. Ini akan mengurangi waktu respons secara signifikan jika Anda membuat beberapa permintaan ke API pihak ketiga dan karenanya akan meningkatkan pengalaman pengguna.

Anda dapat mempelajari lebih lanjut tentang fitur ini di PR ini.