Mengapa kosakata kecil yang tetap dipandang sebagai keuntungan bagi layanan RESTful?

13

Jadi, layanan RESTful memiliki seperangkat kata kerja tetap dalam kosa katanya. Layanan web yang tenang mengambil ini dari metode HTTP. Ada beberapa keuntungan untuk mendefinisikan kosakata tetap, tetapi saya tidak begitu mengerti maksudnya. Mungkin seseorang bisa menjelaskannya.

Mengapa kosakata tetap seperti yang diuraikan oleh REST lebih baik daripada mendefinisikan kosakata secara dinamis untuk setiap negara? Misalnya, pemrograman berorientasi objek adalah paradigma populer. RPC dijelaskan untuk mendefinisikan antarmuka tetap, tetapi saya tidak tahu mengapa orang menganggap bahwa RPC dibatasi oleh kendala ini. Kami dapat menentukan antarmuka secara dinamis sama seperti layanan RESTful secara dinamis menjelaskan struktur kontennya.

REST seharusnya menguntungkan karena dapat tumbuh tanpa menambah kosakata. Layanan tenang tumbuh secara dinamis dengan menambahkan lebih banyak sumber daya. Apa salahnya memperluas layanan dengan secara dinamis menentukan kosakata per objek? Mengapa kita tidak menggunakan metode yang didefinisikan pada objek kita sebagai kosa kata dan meminta layanan kita menjelaskan kepada klien apa metode ini dan apakah mereka memiliki efek samping atau tidak?

Pada dasarnya saya merasa bahwa deskripsi struktur sumber daya sisi server setara dengan definisi kosakata, tetapi kita kemudian dipaksa untuk menggunakan kosakata terbatas untuk berinteraksi dengan sumber daya ini.

Apakah perbendaharaan kata benar-benar memisahkan perhatian klien dari kekhawatiran server? Saya pasti harus khawatir dengan beberapa konfigurasi server, ini biasanya lokasi sumber daya di layanan tenang. Mengeluh pada penggunaan kosakata dinamis sepertinya tidak adil karena kita harus secara dinamis memberi alasan bagaimana memahami konfigurasi ini dalam beberapa cara. Layanan RESTful menggambarkan transisi yang dapat Anda lakukan dengan mengidentifikasi struktur objek melalui hypermedia.

Saya hanya tidak mengerti apa yang membuat kosakata tetap lebih baik daripada kosakata dinamis yang menggambarkan diri sendiri, yang dapat dengan mudah bekerja dengan sangat baik dalam layanan seperti RPC. Apakah ini hanya alasan yang buruk untuk membatasi kosakata protokol HTTP?

Refleksi

Hanya untuk memperjelas pikiran saya sedikit lebih baik daripada yang telah saya lakukan. Misalkan Anda merancang API tujuan umum, bahkan mungkin tidak menghadap ke web. Apakah Anda senang jika seseorang berkata Anda hanya bisa menggunakan nama metode ini pada objek Anda? REST tidak terbatas pada HTTP, tetapi pertimbangkan situasi di mana setiap API yang Anda tulis, menghadap web, atau hanya terdiri dari objek yang berisi GET POST PUT dan DELETE. Jadi metode object.foo yang ingin Anda tetapkan tidak mungkin. Anda harus mendefinisikan objek baru bernama foo, dan memanggil metode GET-nya. Pada dasarnya itulah cara REST bekerja, dan itu membuat saya sedikit tidak nyaman untuk memikirkannya. Anda tidak memiliki pemahaman generik yang lebih baik tentang apa yang dilakukan foo, Anda hanya dipaksa untuk membuat objek baru untuk apa yang pada dasarnya adalah metode pada objek induk. Lebih lanjut, API Anda tidak kalah rumit, Anda baru saja menyembunyikan kompleksitas antarmuka dengan membuat lebih banyak objek. Layanan web RESTful memaksa kami untuk mengadopsi antarmuka yang mungkin atau mungkin tidak cukup dalam konteks API yang kami paparkan. Mungkin ada alasan bagus untuk melakukan ini dengan API yang menghadap web, tetapi alasan yang baik untuk tidak mengadopsi antarmuka standar untuk setiap objek di setiap API tujuan umum. Contoh praktis akan dihargai.

Matt Esch
sumber
Untuk membantu pengguna dengan cepat menguraikan pertanyaan dan jawaban Anda, Anda dapat mempertimbangkan untuk menambahkan "Pembaruan" sebagai jawaban yang terpisah (khususnya bagian "Pembaruan Lain"). Ini dianjurkan: blog.stackoverflow.com/2011/07/...
Johann
@ Johann terima kasih, pembaruan lebih lanjut sekarang ada sebagai jawaban yang diterima untuk pertanyaan ini.
Matt Esch

Jawaban:

9

Terminologi "kata kerja" dan "kata benda" agak disayangkan di sini. Seperti yang telah Anda sebutkan, Anda dapat dengan mudah membuat objek untuk fungsi. Semua bahasa berorientasi objek kecuali Java memiliki transformasi bawaan dan di Jawa Anda akhirnya melakukannya sepanjang waktu dan berakhir dengan banyak objek dengan metode tunggal dan sering disebut "invoke", "execute", "apply", atau somesuch (jadi itu bahasa pemrograman di mana perbedaan "kata kerja" / "kata benda" sebenarnya tidak masuk akal).

"Kata kerja" REST lebih seperti mengklasifikasikan metode Anda ke getter, setter (deleter; dapat dianggap jenis setter) dan lainnya. Dan berusaha melakukan segalanya dengan getter dan setter. Alasan untuk ini adalah:

  1. Semantik yang lebih mudah dalam menghadapi kegagalan komunikasi, karena getter dan setter idempoten. Mendapatkan sumber daya dua kali tidak memiliki efek tambahan dan juga tidak menetapkannya ke nilai yang sudah dimilikinya.
  2. Mendefinisikan beberapa semantik yang dapat digunakan oleh kemungkinan caching proxy yang tidak memahami antarmuka spesifik. Getters di-cache dan setters dikenal untuk membatalkan cache.

HTTP dirancang sejak awal dengan mempertimbangkan cache dan toleransi kesalahan, jadi dua poin ini mengarah pada empat metode dasar:

  • GETadalah rajin dan giat. Diasumsikan tidak mengubah kondisi server dan mengembalikan nilai yang sama setiap kali dengan kemungkinan untuk menentukan kebijakan kedaluwarsa dan validasi ulang.
  • PUTdan DELETEadalah setter dan deleter (= setter dengan nil). Mereka biasanya tidak digunakan dalam konteks web normal, tetapi masuk akal untuk REST.
  • POST adalah "kitchen sink" generik yang tidak dapat digunakan cache.

REST adalah pola desain yang menggambarkan cara menggunakan HTTP mentah atau protokol jaringan serupa untuk mengimplementasikan antarmuka yang memungkinkan penanganan kegagalan dengan mudah dengan mencoba ulang yang baru dan bekerja dengan baik dengan proxy caching.

Itu tidak mudah berhubungan dengan pemrograman API berorientasi objek biasa. Saya pikir itu sebenarnya hal yang baik. Tantangan interfacing melalui jaringan, yang secara inheren tidak dapat diandalkan dan di mana pulang pergi jauh lebih lambat daripada mentransfer bahkan jumlah data panggilan moderat untuk pendekatan desain yang berbeda dari API dalam proses, jadi ketika itu terlihat berbeda, orang tidak mencoba untuk menerapkan pengalaman tidak valid dari domain lain yang banyak (itu kutukan dari SOAP, XML-RPC dan semacamnya; sepertinya panggilan prosedur, tetapi tidak bekerja seperti itu dan akhirnya menjadi sakit untuk bekerja dengan).

Jan Hudec
sumber
2

Ide penting adalah bahwa kompleksitas diekspresikan melalui representasi sumber daya, sehingga kata kerja tambahan tidak diperlukan. Seperti yang dikatakan beberapa orang - "Dalam REST, kata benda baik, kata kerja buruk."

Jika Anda melihat keempat kata kerja REST, mereka dapat dipetakan ke operasi CRUD dasar, yang pada dasarnya memungkinkan Anda untuk melakukan apa pun yang Anda inginkan dengan sumber daya Anda. Itu adalah -

POST - Buat sumber daya

DAPATKAN - Baca sumber daya

PUT - Perbarui sumber daya

HAPUS - Hapus sumber daya

Apa lagi yang kamu butuhkan?

Craig Schwarze
sumber
Saya dapat memfasilitasi kata kerja dalam layanan RESTful dengan menciptakan sumber daya untuk melakukannya. Seperti yang Anda katakan, saya tidak perlu kata kerja tambahan hanya lebih banyak sumber daya. Saya tidak mengerti mengapa lebih baik berpura-pura kata kerja abstrak adalah kata benda padahal yang ingin saya lakukan benar-benar kata kerja. Sepertinya kata kerja dibatasi secara paksa tanpa alasan, dan saya menghindari masalah dengan membuat kata benda yang melakukan tindakan yang diperlukan ketika diakses dengan satu set kata kerja yang kecil. Mengapa lebih baik melakukan itu? Pasti ada alasan bagus untuk itu, sesuatu yang bisa saya ukur sebagai contoh praktis.
Matt Esch
4
Dapatkan daftar semua sumber daya, dapatkan daftar semua sumber daya dengan batasan yang diberikan, perbarui atau hapus banyak sumber daya secara bersamaan, buat dua jenis sumber daya yang berbeda secara bersamaan (sehingga kedua kreasi gagal atau berhasil), hapus semua sumber daya satifikasi suatu kondisi tertentu ... Daftar hal-hal yang mungkin ingin dilakukan seseorang cukup panjang. Orang dapat memasukkannya ke dalam REST API, tetapi itu tidak selalu alami. Ini juga tidak membantu bahwa GET tidak memungkinkan tubuh, sehingga kondisi penyaringan yang kompleks menjadi akward.
Andrea
Sumber daya PATCHing juga cukup keren.
Wyatt Barnett
2

Pertimbangkan bahasa di mana semua konstruksi (seperti fungsi) adalah objek. Kemudian kata kerja RESTful hanya memanggil konvensi dan pernyataan tugas. Untuk JavaScript Anda bisa mendefinisikan sintaks kata kerja tetap seperti INVOKE untuk memanggil fungsi, DELETE (sama dengan delete dalam js) untuk menghapus objek pada objek lain, SET untuk menetapkan nilai dan KEMBALI untuk mengembalikan nilai. Kita bisa menggunakan kata kerja HTTP untuk mengartikan fungsi POST - invoke, PUT - assign value, GET - return a value, - DELETE - delete a object. Saya terperangkap dalam gagasan bahwa metode HTTP sebenarnya menggambarkan metode objek, antarmuka objek aktual, bahwa saya gagal melihat bahwa sebenarnya bisa menggambarkan konsep tingkat jauh lebih rendah, seperti konstruksi bahasa dasar yang jelas-jelas diperbaiki dan terbatas di semua bahasa waras.

Dan tentu saja sangat membantu untuk merutekan / proxying untuk memiliki kosakata tetap untuk direfleksikan.

Matt Esch
sumber
1
  • Karena seorang programmer profesional mengantisipasi ratusan, jika tidak ribuan nama metode sebaliknya. Apa yang tampak tidak berarti pada ukuran yang lebih kecil dapat menjadi masalah yang sangat besar karena aplikasi menjadi lebih besar.

  • Karena tidak perlu standar tentang nama metode ketika sudah ditentukan.

  • Karena tujuan utama kode dapat dibaca tanpa terjemahan tambahan tersebut.

  • Karena itu mendorong dan membantu dalam identifikasi 'kapan' kelas lain harus pecah.

  • Ketika Anda mengambil alih kode itu masuk akal dan sebenarnya mungkin untuk memahami apa dan bagaimana melakukannya lebih cepat.

  • Ini memberikan kosakata umum dan tingkat abstraksi sehingga Anda dapat fokus pada detail lain dan melihat pola.

  • Itu membuat menemukan bug lebih mudah karena kode umum dan pendekatan mudah diperiksa.

  • Saat Anda bekerja dengan beberapa 'lapisan' seperti yang dilakukan dalam pengembangan web, mengetahui url apa yang cocok dengan nama tindakan yang sangat berguna untuk debugging.

Secara keseluruhan Anda tidak 'selalu' membutuhkannya, tetapi seperti kebanyakan standar, akan sangat masuk akal untuk mencoba menggunakannya!

Michael Durrant
sumber
Ditujukan dalam urutan 1) Jadi seorang programmer mengantisipasi ratusan jika tidak ribuan sumber daya? Kami sudah mengantisipasi metode di perpustakaan yang kami gunakan. 2) Jadi kita membutuhkan standar untuk nama metode tetapi tidak untuk nama sumber daya? Saya gagal mengikuti logika itu. 3) Tidak yakin apa yang Anda maksud dengan terjemahan. Jika Anda memberi tahu saya ada sumber daya, saya harus memahaminya. Jika saya memberi tahu Anda suatu metode ada, Anda harus memahaminya. Satu-satunya hal yang benar-benar saya pedulikan adalah tindakan saya mana yang akan memiliki efek samping 4) Bisakah Anda mengembangkannya
Matt Esch
5) lagi bisa Anda kembangkan. Saya seorang programmer. Saya terbiasa bekerja dengan struktur objek yang terdefinisi dengan baik. Mengapa kami tidak menggunakan mekanisme yang sama untuk mendefinisikan semua API kami jika itu benar-benar lebih baik? 6) Tidak ada tingkat abstraksi yang layak dipertimbangkan tanpa pembenaran 7) Lagi-lagi Anda bisa berkembang. Jika kita mendapat manfaat dengan cara ini tentunya kita harus kode semua API kita seperti ini. 8) Saya akan mengharapkan objek apa pun untuk mengekspos metodenya secara langsung. / object / method tidak bisa bingung. Kami mendefinisikan standar dengan memilih untuk mengadopsinya. Saya kurang motivasi saat ini.
Matt Esch
Matt Anda tampaknya sedikit argumentatif tetapi saya akan mengatakan bahwa untuk 2) Saya tidak mengatakan sumber daya tidak akan memerlukan standar 3) Anda tidak perlu memahami metode seperti 'pembaruan' atau 'baru' atau buat 'karena Anda tahu persis apa yang mereka lakukan sesuai dengan standar. Namun bagaimana dengan 'MsgToPrimary' apa fungsinya? Buat pesan? Perbarui status? Kirim Sebuah email? 7) Ya, sebagian besar API dapat memanfaatkan hal ini dan banyak yang melakukannya. Saya akan mencoba untuk fokus pada pengertian standar dan konvensi yang bermanfaat dan saya dapat melihat pembaruan Anda menunjukkan itu.
Michael Durrant
Saya hanya berusaha keras untuk memahami manfaatnya. Argumen tandingan yang kuat perlu ditangani untuk mengklarifikasi masalah. Masih saya mengerti bahwa seperangkat kata kerja tetap adalah semacam deskripsi bahasa, tetapi saya tidak benar-benar setuju bahwa itu membuat lebih mudah untuk dipahami. Anda tidak dapat menghilangkan satu set kata kerja ekspresif dan berkata hei, kami sekarang mengerti semua kata kerja, ketika kami tidak mengerti semua sumber daya. Sumber daya menggantikan kata kerja. Kami mengganti foo kata kerja yang berubah-ubah dengan sumber yang disebut foo. Pemahaman kita tentang foo tidak lebih jelas daripada ketika foo adalah kata kerja.
Matt Esch
1

Alternatifnya adalah sesuatu yang mengerikan: WSDL (alias Web Service Definition Language), yang merupakan cara (kikuk) untuk menggambarkan secara terprogram (agak) APIS sewenang-wenang.

REST sangat membatasi kata kerja, mendorong hampir semua variasi spesifik aplikasi ke dalam muatan dokumen. Manfaat melakukan itu adalah bahwa banyak implementasi klien dapat berkomunikasi dengan banyak layanan heterogen. Klien dan server mungkin sama sekali tidak dikenal satu sama lain, beberapa belum ditulis.

Ada podcast di mana Stefan Tilkov menjelaskan REST dengan baik .

cbare
sumber
1

Ya api sisanya memiliki seperangkat kata kerja tetap, tetapi tidak harus terbatas pada (atau termasuk GET, POST, PUT, DELETE). Saya akan melihat GET, POST, PUT, DELETE sebagai implementasi standar REST yang bekerja untuk 80% dari semua sistem di luar sana.

Sistem lain yang menerapkan lebih dari operasi kasar dapat (dan memang) menerapkan kata kerja mereka sendiri untuk API REST mereka. Kata kerja seperti Publikasikan, Konsumsi, Nilai, Komentar, Cari, Jelajahi dapat ditambahkan dan diimplementasikan dalam sistem REST. Sementara beberapa orang mungkin mengatakan bahwa kosakata yang lebih besar mungkin membuatnya lebih rumit, jawaban saya adalah itu tergantung. Jika pengguna target Anda adalah kepala teknologi yang mengerti apa itu POST maka ya itu bisa lebih rumit; namun, jika pengguna target API Anda adalah orang-orang nyata (yaitu orang-orang yang tidak kode dan tidak tahu apa itu POST), maka kata kerja nyata jauh lebih mudah digunakan. Sebenarnya memiliki seperangkat kata kerja yang sesuai untuk API Anda membantu menjaga url tetap singkat (yang penting jika Anda ingin pengguna mengetikkannya di browser. Jika Anda menggunakan kosakata khusus, Anda harus d ingin memastikan bahwa API Anda dan kata kerjanya terdokumentasi dengan baik. Saat menggunakan api REST khusus, Anda ingin memastikan bahwa 'tindakan hanya baca' Anda sebagai GET HTTP dan 'tulis tindakan' dengan POST.

Jejaring sosial remaja, Piczo.com, (semoga tenang) menampilkan API REST yang diperluas (termasuk kata kerja yang disebutkan di atas) yang diimplementasikan dalam 7 bahasa berbeda!

Andrew
sumber
0

Sederhana itu bagus.

Ada beberapa kasus ketika Anda membutuhkan kata kerja dan kompleksitas tambahan, tetapi sebagian besar masalah dapat dipangkas menjadi tindakan CRUD sederhana pada sumber daya, dan itulah yang coba dipromosikan oleh REST. Ketika Anda berpikir tentang sebagian besar aplikasi web, pada akhirnya mereka membaca dan mempertahankan catatan di penyimpanan data, yang menggunakan tindakan yang sangat sederhana yang sama.

object.foo () semuanya baik, tetapi apa fungsinya? Apa itu kembali? Apakah itu memodifikasi keadaan objek atau ketergantungannya? Bisakah Anda memanggilnya dua kali dan mendapatkan hasil yang sama atau apakah akan memberi Anda dua nilai yang berbeda? Jika Anda memiliki object.bar () juga, apakah mereka perlu dipanggil dalam urutan tertentu?

Ada banyak pengetahuan yang diperlukan dalam menggunakan API yang kaya, dan mereka biasanya memiliki konvensi sendiri (yaitu setFoo akan mengubah objek, getBar mungkin idempoten, membuang () atau menghancurkan () berarti tidak ada panggilan lain pada objek yang sama akan mungkin, dll ...)

ptyx
sumber