Apa gunanya dengan HATEOAS di sisi klien?

35

Seperti yang saya pahami, HATEOAS pada dasarnya adalah tentang mengirim bersama dengan setiap tautan tanggapan dengan informasi tentang apa yang harus dilakukan selanjutnya. Satu contoh sederhana mudah ditemukan di internet: sistem perbankan bersama dengan sumber daya akun. Contoh ini menunjukkan respons ini setelah permintaan GET ke sumber daya akun

GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK 
<?xml version="1.0"?> 
<account> 
    <account_number>12345</account_number> 
    <balance currency="usd">100.00</balance> 
    <link rel="deposit" href="/account/12345/deposit" /> 
    <link rel="withdraw" href="/account/12345/withdraw" /> 
    <link rel="transfer" href="/account/12345/transfer" /> 
    <link rel="close" href="/account/12345/close" /> 
</account>

Bersama dengan data ada tautan yang memberi tahu apa yang bisa dilakukan selanjutnya. Jika saldo negatif kita miliki

GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK 
<?xml version="1.0"?> 
<account> 
    <account_number>12345</account_number> 
    <balance currency="usd">-25.00</balance> 
    <link rel="deposit" href="/account/12345/deposit" /> 
</account>

Sehingga kita hanya bisa melakukan setoran. Tidak apa-apa, jika kita menggunakan Fiddler atau membuat permintaan dengan browser, kita dapat dengan mudah melihat apa yang bisa dilakukan. Informasi semacam ini berguna bagi kita untuk menemukan kemampuan API dan server dipisahkan dari klien.

Namun, intinya adalah bahwa ketika kita membangun klien, seperti SPA dengan Javascript, atau aplikasi Android atau banyak hal lainnya, saya tidak dapat melihat bagaimana HATEOAS terus menjadi relevan. Yang saya maksud adalah sebagai berikut: ketika saya sedang mengkode SPA dalam javascript, saya harus tahu apa yang bisa dilakukan dalam API untuk menulis kode.

Jadi saya perlu tahu sumber daya, metode yang didukung, apa yang mereka harapkan untuk terima dan apa yang mereka berikan kembali untuk menulis ajax panggilan ke server dan bahkan untuk membangun UI. Ketika saya membangun UI, saya harus tahu bahwa setelah meminta akun, seseorang dapat, misalnya, menyetorkannya, atau saya tidak akan dapat memberikan opsi ini pada UI. Juga, saya harus tahu URI untuk melakukan setoran untuk membangun panggilan ajax.

Maksud saya adalah, ketika kita membuat permintaan ke API, tautan memungkinkan kita menemukan dan menggunakan API dengan lebih baik, tetapi ketika kita membangun klien, aplikasi yang kita bangun tidak akan hanya melihat tautan dan kemudian dengan sendirinya membuat UI yang benar dan lakukan panggilan ajax yang tepat.

Jadi, bagaimana HATEOAS penting bagi klien? Kenapa sih kita repot-repot dengan HATEOAS?

pengguna1620696
sumber
1
Anda benar, tapi bukan itu intinya. HATEOAS mencegah Anda membuat URI untuk tautan di halaman pada klien.
James McLeod

Jawaban:

24

aplikasi yang kami bangun tidak akan hanya melihat tautan dan kemudian dengan sendirinya merender UI yang benar dan melakukan panggilan ajax yang tepat

Bahkan, ini adalah persis apa yang HATEOAS akan memberikan UI. Bukan apa yang mungkin, tetapi ketika itu mungkin. HATEOAS formal seperti HAL , seperti yang dinyatakan dalam pertanyaan, memberikan tautan yang menunjukkan apa yang mungkin. Tetapi ketika tautan itu muncul tergantung pada kondisi aplikasi. Jadi, tautan dapat berubah pada sumber daya seiring waktu (berdasarkan tindakan yang telah dilakukan).

Ini memungkinkan kami untuk membangun UI yang berisi semua status yang mungkin , tetapi tidak khawatir ketika negara-negara tersebut menjadi aktif. Misalnya, kehadiran rel="deposit"kaleng langsung memberi tahu UI kapan OK untuk merender make depositformulir. Yang kemudian memungkinkan pengguna untuk memasukkan nilai dan mengirimkan menggunakan tautan.

Davin Tryon
sumber
2
Jadi ketika membangun UI kita masih perlu tahu semua yang ditawarkan API, dan kemudian melihat tautan-tautan itu kita dapat mengetahui status informasi di server? Jadi misalnya, UI tahu itu mungkin untuk menyetor, menarik, mentransfer atau menutup (tahu rel yang mungkin), lalu memeriksa apa yang kembali untuk melihat keadaan?
user1620696
1
Ya bisa. Sekali lagi itu tergantung pada seberapa dinamis yang Anda inginkan. Seperti yang disebutkan orang lain, kemampuan untuk mengubah tautan di server (dan tidak memutus klien) adalah keuntungan lain. Dan ini menjadi sangat menarik setelah API Anda memiliki iPhone, Android, Windows Phone, Mobile Web, dan klien Web yang semuanya menggunakannya (belum lagi jika API Anda diterbitkan untuk orang lain untuk membangun klien).
Davin Tryon
@ user1620696 Anda harus mengetahui semua ini melalui klien dan server yang meremehkan jenis konten jika sumbernya. Jenis konten jauh lebih banyak daripada xml bodoh atau Json. Anda harus memiliki beberapa jenis konten "setoran bank" yang dapat dipahami klien saat bekerja
Cormac Mulhall
1
@Nik, lihat HAL untuk contoh bagaimana tautan disediakan dalam respons.
Davin Tryon
1
ya, Anda masih memiliki masalah kompatibilitas ke belakang. Ini dapat diatasi dengan memasukkan header versi atau versi di url. Tapi, saya akan mengatakan Anda mengerti dengan benar.
Davin Tryon
3

Seperti yang saya pahami, HATEOAS pada dasarnya adalah tentang mengirim bersama dengan setiap tautan tanggapan dengan informasi tentang apa yang harus dilakukan selanjutnya

HATEOAS lebih dari sekadar tautan. Ini adalah "hyper media" sebagai mesin negara aplikasi.

Apa yang terlewatkan dalam deskripsi Anda adalah tipe konten, definisi formal dari hyper media yang dilewatkan antara klien dan server.

HTML adalah contoh hyper media, dan contoh mengapa HATEOS bekerja. Halaman HTML itu sendiri adalah mesin yang memungkinkan klien (yaitu pengguna) untuk bergerak melalui situs. Browser dengan hanya kemampuan untuk menyajikan HTML kepada pengguna situs web yang sepenuhnya dinavigasi. Bukan hanya karena ia mengirimkan tautan ke halaman lain, tetapi juga mengirimkannya dengan cara yang bermakna yang memberikan konteks pada tautan dan dengan cara yang memungkinkan browser untuk membangun situs yang dapat dilayari.

Dan yang paling penting browser dapat melakukan ini dengan NOL pemahaman di muka situs web itu sendiri. Browser hanya tahu HTTP dan HTML. Berdasarkan pemahaman sederhana itu dapat menyajikan New York Times kepada pengguna untuk menavigasi.

Ini berlaku bahkan jika "pengguna" adalah program komputer lain. Hyper media itu sendiri harus menentukan konteks navigasi.

Cormac Mulhall
sumber
1
Tidakkah ini berarti Anda harus membangun klien yang kompleks (dan rawan bug) sebagai peramban? Fleksibilitas sering kali disertai dengan kerumitan sebagai biaya ...
Andres F.
@AndresF. itu tidak berarti bahwa Anda harus atau harus melakukannya, itu hanya memberi Anda pilihan untuk melakukannya secara dinamis jika Anda mau atau membutuhkannya.
Peteris
2
@ Ya Tentu. Dari atas kepala saya bayangkan bahwa Anda memiliki layanan yang menyediakan informasi nenek moyang melalui api nyenyak. Anda memiliki jenis konten yang menentukan format sumber daya 'Orang' yang memiliki berbagai informasi tentang mereka tetapi juga menentukan seperti apa hubungan itu, katakanlah 'saudara lelaki' atau 'saudara perempuan' atau 'ibu' dll. Karena ini adalah hypermedia, hubungan-hubungan itu hanya memiliki URI ke sumber daya Orang lain. Klien yang cukup sederhana menggunakan kata kerja HTTP dan memahami tipe konten 'Orang' ini dapat menavigasi melalui API ini. Katakanlah Anda ingin menemukan semua keturunan langsung dari orang tertentu.
Cormac Mulhall
2
@nik Klien ini perlu memahami secara sederhana tipe konten dari sumber daya yang telah diaksesnya dan kata kerja HTTP (GET, PUT, DELETE dll) dan Anda dapat menavigasi melalui API ini mengambil dan memperbarui sumber daya. Dan, yang lebih penting, klien mana pun yang memahami tipe konten dapat melompat, melalui URI, ke server lain sepenuhnya dan melanjutkan seperti semula. Mereka tidak peduli server apa yang mereka ajak bicara, mereka hanya peduli pada jenis konten sumber daya, apakah mereka memahaminya atau tidak.
Cormac Mulhall
1
@Nik Jadi dalam situasi seperti ini Anda memiliki server yang memahami tipe konten asli (katakanlah Person v1) dan tipe konten baru (Person v2). Klien hanya memahami Orang v1. Klien memberi tahu server jenis konten apa yang dipahami melalui tajuk Terima di HTTP. Menggunakan negosiasi konten server menentukan apakah ia akan mengirim apa yang didukung klien, dalam hal ini akan mengembalikan sumber daya menggunakan tipe konten Person v1. Sekarang Anda mungkin ingin berhenti mendukung jenis konten lama ini dan dapat mengirim kesalahan kepada klien 406. Lebih baik untuk mencoba dan mendukung sebanyak yang Anda bisa.
Cormac Mulhall
2

Anda tidak harus membangun antarmuka yang dihasilkan secara dinamis. Meskipun itu bisa menyenangkan, itu tidak diperlukan. Jika Anda tidak dapat membangun antarmuka dinamis, cukup gunakan tautan dan Anda selesai. Kerugiannya adalah Anda lagi-lagi sulit ditautkan ke backend dan akan macet jika ada perubahan.

Menggunakan tata letak dinamis bisa sangat sederhana:

links.forEach(function(link) {

  switch(link.rel) {

    case 'deposit':
      showDepositButton();
      break;

    case 'withdraw':
      loadWithdrawForm(link.href);
      showWithdrawButton();
      break;
  }

});

Ini menghemat Anda dalam kode klien Anda seperti:

if (balance <= 0 && negativeBalanceAllowed === false) {
  showWithdrawButton();
}

Anda dapat menerapkan posisi negatif yang diizinkan (dengan meminjam uang misalnya) tanpa mengubah klien Anda.

Luc Franken
sumber
Sebagai contoh yang sedikit lebih kuat, bank dapat menawarkan batas cerukan variabel pada rekening mereka, tanpa harus memberi tahu sisi klien berapa batas pada setiap rekening.
Bart van Ingen Schenau
Benar, Anda dapat membuat keputusan batas keseimbangan serumit yang Anda inginkan dan masih tidak harus melakukan perubahan pada klien. Jika Anda mengambil ini lebih jauh dengan bagian REST seperti jenis konten Anda dapat menampilkan tampilan yang berbeda. Misalnya akun terlihat berbeda dari transaksi. Yang juga menarik adalah kode sesuai permintaan (meskipun tidak banyak diterapkan). Itu bisa digunakan misalnya untuk penduga pinjaman. Ini dapat memberikan antarmuka fungsi kalkulator sederhana sehingga klien hanya perlu mengimplementasikan input untuk perhitungan. Itu akan tetap up-to-date dari back-end.
Luc Franken
2
Tetapi biasanya pelanggan perlu tahu MENGAPA itu tidak bisa ditarik, jadi kami masih perlu mengirim ENUM atau String di bidang terpisah ke klien dengan reason. Dan jika kita masih membutuhkan ini, mengapa tidak mengirimnya bidang boolean lain canWithdrawsebagai ganti tautan ke tindakan? Keuntungan lain adalah kemampuan untuk mengubah URL tindakan tanpa menyentuh klien. Tapi .. alasan apa untuk mengubah URL? Dalam kebanyakan kasus itu juga beberapa perubahan dalam semantik atau parameter atau bentuk permintaan / respons dll. Jadi kita tetap perlu mengubah klien. Jadi, saya masih belum mengerti - apa gunanya HATEOAS.
Ruslan Stelmachenko