Apakah REST API Itu Benar-benar RPC? Roy Fielding Sepertinya Berpikir Begitu

99

Sebagian besar dari apa yang saya pikir saya ketahui tentang REST ternyata salah - dan saya tidak sendiri. Pertanyaan ini memiliki petunjuk yang panjang, tetapi tampaknya perlu karena informasinya agak tersebar. Pertanyaan sebenarnya muncul di bagian akhir jika Anda sudah terbiasa dengan topik ini.

Dari paragraf pertama REST API Roy Fielding harus digerakkan oleh hypertext , cukup jelas dia yakin karyanya disalahartikan secara luas:

Saya merasa frustrasi dengan jumlah orang yang memanggil antarmuka berbasis HTTP apa pun sebagai REST API. Contoh hari ini adalah SocialSite REST API . Itu adalah RPC. Ia berteriak RPC. Ada begitu banyak kopling yang dipamerkan sehingga harus diberi peringkat X.

Fielding melanjutkan dengan mendaftar beberapa atribut REST API. Beberapa dari mereka tampaknya bertentangan dengan praktik umum dan saran umum di SO dan forum lainnya. Sebagai contoh:

  • REST API harus dimasukkan tanpa pengetahuan sebelumnya di luar URI awal (bookmark) dan kumpulan jenis media standar yang sesuai untuk audiens yang dituju (yaitu, diharapkan dapat dipahami oleh klien mana pun yang mungkin menggunakan API). ...

  • REST API tidak boleh menentukan nama atau hierarki sumber daya tetap (penggabungan klien dan server yang jelas). ...

  • REST API harus menghabiskan hampir semua upaya deskriptifnya dalam menentukan jenis media yang digunakan untuk mewakili sumber daya dan mendorong status aplikasi, atau dalam menentukan nama relasi yang diperluas dan / atau markup yang mendukung hypertext untuk jenis media standar yang ada. ...

Ide "hypertext" memainkan peran sentral - lebih dari sekedar struktur URI atau apa arti kata kerja HTTP. "Hypertext" didefinisikan di salah satu komentar:

Ketika saya [Fielding] mengatakan hypertext, yang saya maksud adalah penyajian informasi dan kontrol secara simultan sedemikian rupa sehingga informasi tersebut menjadi kemampuan di mana pengguna (atau robot) memperoleh pilihan dan memilih tindakan. Hypermedia hanyalah perluasan dari arti teks untuk memasukkan jangkar temporal dalam aliran media; kebanyakan peneliti telah menghilangkan perbedaannya.

Hypertext tidak harus berupa HTML di browser. Mesin dapat mengikuti tautan ketika mereka memahami format data dan tipe hubungan.

Saya menebak pada titik ini, tetapi dua poin pertama di atas tampaknya menyarankan bahwa dokumentasi API untuk sumber daya Foo yang terlihat seperti berikut ini mengarah pada hubungan erat antara klien dan server dan tidak memiliki tempat dalam sistem RESTful.

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

Sebaliknya, agen harus dipaksa untuk menemukan URI untuk semua Foos dengan, misalnya, mengeluarkan permintaan GET terhadap / foos. (URI tersebut mungkin ternyata mengikuti pola di atas, tetapi bukan itu intinya.) Respons menggunakan jenis media yang mampu menyampaikan cara mengakses setiap item dan apa yang dapat dilakukan dengannya, sehingga memunculkan poin ketiga di atas . Untuk alasan ini, dokumentasi API harus fokus pada penjelasan bagaimana menginterpretasikan hypertext yang terkandung dalam respon.

Selain itu, setiap kali URI ke sumber daya Foo diminta, respons berisi semua informasi yang diperlukan agen untuk menemukan cara melanjutkan, misalnya, mengakses sumber daya terkait dan induk melalui URI mereka, atau dengan mengambil tindakan setelah pembuatan. / penghapusan sumber daya.

Kunci dari keseluruhan sistem adalah bahwa respon terdiri dari hypertext yang terdapat dalam jenis media yang dengan sendirinya menyampaikan ke opsi agen untuk melanjutkan. Ini tidak berbeda dengan cara kerja browser untuk manusia.

Tapi ini hanya tebakan terbaik saya pada saat ini.

Fielding memposting tindak lanjut di mana dia menanggapi kritik bahwa pembahasannya terlalu abstrak, kurang contoh, dan kaya jargon:

Orang lain akan mencoba menguraikan apa yang telah saya tulis dengan cara yang lebih langsung atau dapat diterapkan untuk beberapa masalah praktis saat ini. Saya mungkin tidak akan melakukannya, karena saya terlalu sibuk bergumul dengan topik berikutnya, mempersiapkan konferensi, menulis standar lain, bepergian ke suatu tempat yang jauh, atau hanya melakukan hal-hal kecil yang membuat saya merasa telah mendapatkan gaji saya.

Jadi, dua pertanyaan sederhana untuk pakar REST di luar sana dengan pola pikir praktis: bagaimana Anda menafsirkan apa yang dikatakan Fielding dan bagaimana Anda mempraktikkannya saat mendokumentasikan / menerapkan REST API?

Sunting: pertanyaan ini adalah contoh betapa sulitnya mempelajari sesuatu jika Anda tidak memiliki nama untuk apa yang Anda bicarakan. Nama dalam hal ini adalah "Hypermedia sebagai Mesin Negara Aplikasi" (HATEOAS).

Apodaca Kaya
sumber
26
John, Rich baru saja menjelaskan perubahan pola pikir yang dimilikinya. Tidak ada yang subjektif atau argumentatif tentang itu. Pilih untuk tetap terbuka - ini adalah salah satu pertanyaan yang lebih baik dengan tag 'istirahat' yang pernah saya lihat di SO.
Keith Gaughan
4
Keith, "menjelaskan perubahan pola pikir" adalah sesuatu yang harus dia lakukan di blognya, bukan di SO.
John Saunders
13
Dia tidak menjelaskan perubahan pola pikirnya, dia menanyakan apakah pemahamannya akurat.
aehlke
4
Ringkasan yang bagus. Saya belajar lebih banyak dari pertanyaan ini daripada kebanyakan jawaban.
Martin Konecny

Jawaban:

21

Saya pikir penjelasan Anda sebagian besar mencakupnya. URI adalah pengenal buram yang, untuk sebagian besar, tidak dikomunikasikan di luar URI bookmark yang digunakan oleh agen pengguna untuk mengakses aplikasi.

Mengenai pendokumentasian, pertanyaan ini sudah dilakukan beberapa kali. Anda mendokumentasikan jenis media Anda, bersama dengan kontrol hyperlink yang ada di dalamnya (tautan dan formulir), dan model interaksi jika Anda menginginkannya (lihat AtomPub).

Jika Anda mendokumentasikan URI atau cara membuatnya, Anda salah melakukannya.

SerialSeb
sumber
Apakah ini masih benar? Ada spesifikasi respons API seperti Ionspec yang sengaja menjadikan URI ini sebagai bagian dari respons.
Sean Pianka
Ya mereka pernah. Pada titik itu, ini adalah pertanyaan untuk mencari tahu apakah URI yang didokumentasikan tersebut hanyalah titik masuk ke aplikasi, yang dijamin akan tetap ada (beberapa di antaranya tidak biasa dan sangat berguna) atau jika, karena orang menginginkan pembuatan kode, itu disematkan dari spesifikasi langsung ke dalam kode, mencegah server memberi tahu klien tentang bagaimana ia dapat melakukan sesuatu. Jika klien mengira ia tahu karena kontrak itu, Anda tidak berada di hypermedia, Anda menyukai model sabun openapi modern, dengan masalah yang sama yang Anda temui 18 tahun lalu.
SerialSeb
Apa yang benar adalah bahwa banyak bahasa dokumentasi API telah berputar dalam 11 tahun terakhir, tetapi dasarnya tidak berubah. Saya percaya nilai dalam menemukan tautan tersebut, atau setidaknya penemuan template URI, adalah dalam membangun kode klien umum yang dapat digunakan kembali yang dapat secara dinamis menggunakannya, memungkinkan banyak implementasi di sisi server untuk menggunakan kembali kode klien yang sama. Penyematan URI terus mempersulit skenario seperti itu, tetapi jika Anda menggunakan format tersebut, Anda cenderung menghubungkan erat klien yang dihasilkan dari spesifikasi tersebut, jadi Anda sudah kehilangan fitur itu.
SerialSeb
8

Penafsiran Anda tampaknya benar bagi saya. Saya yakin bahwa kendala Fielding dapat diterapkan secara praktis.

Saya benar-benar ingin melihat seseorang mempublikasikan beberapa contoh bagus tentang bagaimana mendokumentasikan antarmuka REST. Ada begitu banyak contoh yang buruk, memiliki beberapa yang valid untuk ditunjukkan kepada pengguna akan sangat berharga.

Darrel Miller
sumber
2
Wow. Halaman Model Sumber Daya itu membuat saya menangis. Mari berharap ini memulai tren.
Darrel Miller
Sayang sekali ini pada dasarnya adalah satu - satunya contoh API semacam itu di web! Lebih buruk lagi, tidak ada contoh bagus dari kode klien yang mengikuti prinsip sama sekali (yang saya temukan).
jkp
1
@DarrelMiller Tapi bukankah Jenis Media itu terlalu "spesifik"? Menurut saya, API mereka benar-benar hanya menggunakan satu MIME:, application/jsondan Model Sumber Daya benar-benar merupakan relasi. Apakah saya salah memahami aspek REST ini? Saya juga telah membaca salah satu jawaban SO Anda yang sepertinya menunjukkan bahwa kontrak "satu atribut" harus dihindari ...
edsioufi
2
@RichApodaca Tautan Anda telah meninggal karena disentri. web.archive.org/web/20170409132237/https://kenai.com/projects/…
forresthopkinsa
5

Saya telah mencari contoh bagus dari API yang ditulis mengikuti HATEOAS dan mengalami kesulitan menemukannya (saya menemukan hal-hal SunCloud API dan AtomPub sulit untuk diterapkan pada situasi API "normal"). Jadi saya mencoba membuat contoh realistis di blog saya yang mengikuti saran Roy Fieldings tentang apa artinya penerapan REST yang tepat. Saya merasa sangat sulit untuk memberikan contoh, meskipun pada prinsipnya cukup sederhana (hanya membingungkan saat bekerja dengan API dibandingkan dengan halaman web). Saya mengerti apa yang dipermasalahkan Roy dan setuju, itu hanya perubahan pola pikir untuk diterapkan dengan benar untuk API.

Lihat: Contoh API menggunakan Istirahat

jeremyh
sumber
4

Satu-satunya pengecualian untuk memberikan instruksi tentang cara membangun URI adalah diizinkan untuk mengirim template URI dalam respons hypertext, dengan bidang yang akan diganti secara otomatis oleh klien, menggunakan bidang lain di hypertext. Ini biasanya tidak menghemat banyak bandwidth meskipun karena kompresi gzip akan menangani bagian URI yang berulang dengan cukup baik untuk tidak repot dengan ini.

Beberapa diskusi bagus tentang REST dan HATEOAS terkait:

Keuntungan Dari (Juga) Menggunakan HATEOAS Di RESTFul API

Cara MENDAPATKAN secangkir kopi

aehlke
sumber
4

Bagi mereka yang tertarik, saya menemukan contoh rinci HATEOAS dalam praktik di Sun Cloud API .

Apodaca Kaya
sumber
2
Link sudah mati. Arsip
wha7ever
4

Hal yang kebanyakan orang salah adalah (setidaknya menurut saya) di dunia REST Anda tidak mendokumentasikan "antarmuka Rest" Anda, apa yang Anda dokumentasikan adalah jenis media, terlepas dari server atau layanan Anda.

redben
sumber
2

Saya pikir selama bertahun-tahun REST telah ada di luar sana sekarang, para ahli teknologi telah mencapai kesepakatan dengan konsep Sumber Daya dan apa yang sebenarnya atau tidak RESTful.

Menurut Richardson Maturity Model, ada 4 level (0-3) yang menentukan seberapa RESTful API Anda, dengan 3 artinya API yang benar-benar RESTful, seperti yang diinginkan Roy Fielding.

Level 0 adalah ketika Anda memiliki satu titik masuk URI - seperti SOAP.

Level 1 berarti API mampu membedakan antara sumber daya yang berbeda, dan memiliki lebih dari satu titik masuk - masih berbau SOAP.

Level 2 adalah saat Anda menggunakan kata kerja HTTP - terutama GET, POST, DELETE. Ini adalah level di mana REST benar-benar muncul.

Di Level 3, Anda mulai menggunakan kontrol hypermedia untuk membuat API Anda benar-benar tenang.

Tautan yang disarankan untuk bacaan lebih lanjut:

Sampada
sumber
1

Tepat sekali. Saya akan mencatat sebagai tambahan bahwa template URI baik-baik saja dalam aplikasi RESTful selama polanya berasal dari dokumen yang diterima dari server (OpenSearch menjadi contoh yang sesuai). Untuk template URI, Anda mendokumentasikan tempat mereka digunakan dan placeholder yang diharapkan dalam template tersebut, tetapi bukan template itu sendiri. Sedikit bertentangan dengan apa yang dikatakan Wahnfrieden, ini bukan pengecualian.

Misalnya, di tempat kerja saya, kami memiliki sistem manajemen domain internal, dan dokumen layanan menetapkan dua template URI: satu untuk menghasilkan URI tebakan terbaik untuk sumber daya domain, dan satu lagi untuk membuat URI untuk menanyakan ketersediaan domain. Masih mungkin untuk melihat-lihat kumpulan domain untuk mencari tahu apa URI dari domain tertentu, tetapi mengingat banyaknya domain yang dikelolanya, ini tidak akan layak untuk klien, jadi memberi mereka cara untuk menebak apa URI dari sumber daya domain mungkin merupakan kemenangan besar dalam hal kemudahan implementasi dari perspektif klien, dan bandwidth dari server.

Mengenai pertanyaan Anda: Dokumentasi normatif kami memaparkan sumber daya, pengaruh berbagai metode pada sumber daya tersebut, dan jenis media representasi yang digunakan dan skemanya, dan jenis sumber daya yang ditunjuk URI dalam representasi tersebut.

Kami juga menyertakan dokumentasi non-normatif (informatif) yang telah melampirkan penafian untuk tidak membaca terlalu banyak ke dalam URI yang disebutkan dalam dokumen, yang memberikan contoh interaksi klien-server yang khas. Ini menempatkan dokumentasi normatif yang agak abstrak dalam istilah konkret.

Keith Gaughan
sumber
1
Tidak masalah untuk menyediakan template URI sebagai bagian dari API Anda, di luar jalur. TOLONG JANGAN menyebut ini sebagai REST, karena memang bukan. Itu jumlah kopling yang sangat besar, dan tepatnya apa yang harus dihindari oleh REST. Tapi seperti yang Anda katakan, REST tidak untuk setiap aplikasi. Jadi jangan berpura-pura setiap aplikasi REST.
aehlke
1
Sebenarnya saya setuju. Saya percaya itulah yang saya katakan. Namun, saya benar-benar tidak dapat melihat alasan yang baik untuk menyediakan template URI out-of-band.
Keith Gaughan
0

Mari kita asumsikan GET /foos/createFormdipanggil untuk mendapatkan nilai bidang formulir yang harus disediakan saat kita pergi untuk membuat POST /foos. Sekarang URL khusus ini, yaitu 1 yang digunakan untuk membuat foo, harus disebutkan dalam tanggapan GET /foos/createFormsebagai tautan kirim tindakan sesuai dengan proposisi Fielding, bukan?
Lalu apa manfaat dari memetakan tindakan ke kata kerja Http terkenal untuk tindakan, "konvensi atas kode / konfigurasi" hal tersebut dibatalkan.

redzedi
sumber