Kata kerja HTTP mana yang harus saya gunakan untuk memicu tindakan di layanan web REST?

81

Saya menerapkan layanan web RESTful dan salah satu tindakan yang tersedia adalah reload. Ini akan digunakan untuk memuat ulang konfigurasi, cache, dll.

Kami mulai dengan GETURI yang sederhana seperti ini: ${path}/cache/reload(tidak ada parameter yang dilewati, hanya URI yang dipanggil). Saya sadar bahwa data tidak boleh dimodifikasi dengan permintaan GET.

Mana kata kerja yang benar untuk digunakan untuk menjalankan tindakan / perintah dalam layanan web RESTful?

Reload adalah perintah dari layanan web REST yang memuat ulang cache / konfigurasi / etc. Ini bukan metode yang mengembalikan informasi ke klien.

Mungkin yang saya coba lakukan bukanlah REST, tetapi masih sesuatu yang perlu dilakukan dengan cara ini. The reloadMetode itu hanya contoh nyata yang masuk akal dalam lingkup aplikasi dan paling jawaban terfokus pada hal itu, namun pada kenyataannya, saya hanya perlu tahu mana kata kerja untuk memicu suatu tindakan yang tidak melakukan CRUD, tapi masih perubahan data / negara.

Saya menemukan asnwer terperinci ini di Stack Overflow tentang subjek: https://stackoverflow.com/questions/16877968/

Renato Dinhani
sumber
1
"Memuat ulang" apakah arti aplikasi menyegarkan data yang akan ditampilkan? Apakah ada perbedaan antara memuat ulang dan hanya mendapatkan data lagi?
Sean Redmond
1
@SeanRedmond Tidak, data tidak dikirim ke klien. Bahkan, adalah klien mengatakan kepada layanan web REST untuk mengeksekusi dan perintah internal (reload). Sesuatu seperti: "banyak konfigurasi diubah dalam database, jadi REST web service, muat ulang ke memori Anda sekarang".
Renato Dinhani
Duplikat lintas-situs: stackoverflow.com/q/15340946/319403
cHao
Sudahkah Anda mempertimbangkan untuk menggunakan parameter header pada permintaan yang sesuai? Ini terdengar seperti penyegaran cache ...
Guran

Jawaban:

25

Saya tidak berpikir ada kata kerja yang tepat untuk tindakan ini karena transaksi ini tidak benar-benar "TENANG." Huruf "s" dan "t" adalah singkatan dari "transfer negara" dan tidak ada yang ditransfer di sini. Atau, dengan kata lain, dengan definisi ketat, kata kerja seperti PUT dan POST selalu digunakan dengan kata benda dan "reload" hanya memiliki kata kerja.

Reload ini mungkin tidak tenang, tetapi mungkin masih berguna dan Anda hanya harus memilih cara untuk melakukannya dan hidup dengan atau menjelaskan bahwa itu tidak biasa. GET mungkin yang paling sederhana. Ada cukup banyak skeptisisme dalam komentar, jadi Anda harus berpikir tentang apakah tindakan memuat ulang ini diperlukan atau tidak karena sesuatu yang lain tidak cukup melakukan apa yang seharusnya dilakukan.

Sean Redmond
sumber
Saya setuju bahwa ini bukan ISTIRAHAT tetapi mungkin berguna. Saya pikir Anda harus menyarankan PUT, karena ini mungkin idempoten tetapi tidak nullimpotent.
Aaron Greenwald
@ Harun, perbandingan idempoten dan nullimpotent baik dan bagus, tapi bagaimana Anda menentukan kapan itu tidak impoten?
Craig
@Craig idempoten jika menjalankannya berkali-kali memiliki efek yang sama dengan menjalankannya sekali. Ini nullipotent jika menjalankannya sekali atau berkali-kali memiliki efek yang sama pada server seperti menjalankannya nol kali. en.wikipedia.org/wiki/Idempotence
Aaron Greenwald
5
@AaronGreenwald “notimpotent” [not-im-poht-nt] [not-im-pawr-tnt] - kata sifat - 1. Sebuah permainan kata-kata, “not important,” antonim dari kata sifat “important.” 2. Humor… ;-)
Craig
@Craig Aku benar-benar merindukan itu :)
Aaron Greenwald
75

Jika Anda ingin TETAP tidak memikirkan kata kerja untuk melakukan suatu tindakan, pikirkan keadaan di mana Anda ingin sumber daya berada setelah klien melakukan sesuatu.

Jadi menggunakan salah satu contoh Anda di atas Anda memiliki antrian email yang mengirim email. Anda ingin klien memasukkan antrian email itu ke status jeda atau dihentikan atau apalah.

Jadi klien PUT keadaan baru ke server untuk sumber daya itu. Ini bisa sesederhana JSON ini

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

Server mengetahui cara keluar dari status saat ini (katakanlah "menjalankan") ke status / keadaan "dijeda".

Jika klien melakukan GET pada sumber daya, ia harus mengembalikan statusnya saat ini (katakan "dijeda").

Alasan untuk melakukannya dengan cara ini, dan mengapa REST bisa sangat kuat, adalah bahwa Anda meninggalkan BAGAIMANA untuk mencapai status itu di server.

Klien hanya mengatakan "Ini adalah keadaan Anda seharusnya sekarang" dan server mencari cara untuk mencapai itu. Ini mungkin flip sederhana dalam database. Mungkin membutuhkan ribuan tindakan. Klien tidak peduli, dan tidak perlu tahu.

Jadi Anda dapat sepenuhnya menulis ulang / mendesain ulang bagaimana server melakukan itu dan klien tidak peduli. Klien hanya perlu menyadari keadaan yang berbeda (dan representasi mereka) dari sumber daya, bukan dari internal.

Cormac Mulhall
sumber
2
Sejauh yang saya ketahui, ini adalah jawaban yang benar. Menyegarkan data di server bukan operasi idempoten, dan GETmerupakan kata kerja yang sepenuhnya tidak pantas untuk digunakan. PUTadalah kata kerja yang paling tepat karena operasi dapat dianggap sebagai memperbarui "status reloaded" dari cache ke "reloaded".
Jez
@ Jo. Dari jawaban di sini, saya lebih suka yang ini juga. Menempel dengan metafora email, begitu saja itu tidak merasa aneh pada awalnya untuk memikirkan mengirim surat dengan menempatkan ke dalam "mengirimkan" negara bukan hanya mengirimkan itu (tindakan). Tetapi jika Anda memikirkannya, itu benar-benar sama dengan meletakkannya di "kotak keluar." Bahkan, sistem e-mail itu sendiri mungkin sedang mengantri secara internal ketika Anda memintanya untuk mengirim. Jadi API dapat membiarkan Anda memasukkan surat dalam status "pengiriman", dan API tidak berkewajiban untuk menjelaskan lebih dari itu.
Craig
Jadi dengan ekstensi, jika Anda tidak ingin pesan pergi dulu, Anda memasukkannya ke dalam status "terjadwal" dengan tanggal / waktu kapan pesan itu akan dirilis. Jika tidak lengkap, Anda letakkan (atau secara implisit / secara default) dalam status "draft", dll.
Craig
... walaupun saya pikir saya lebih suka POST daripada PUT dalam kasus ini, karena PUT juga seharusnya idempoten, tetapi POST tidak ada kendala seperti itu.
Craig
1
Anda bisa melakukannya, tetapi pada akhirnya ia mencoba memasukkan pasak persegi ke dalam lubang bundar. Tidak ada alasan mengapa klien perlu memicu server untuk "memuat kembali" apa pun, itu hanya desain arsitektur yang buruk. Baik server dapat memperbarui status internalnya pada setiap panggilan atau pada interval waktu yang tetap. Mengandalkan klien untuk memberi tahu server untuk memuat ulang sesuatu yang independen dari setiap permintaan aktual untuk status sumber daya bukanlah arsitektur yang tenang.
Cormac Mulhall
32

Beberapa jawaban lain, termasuk yang diterima, menyarankan Anda untuk menggunakan GET (meskipun tidak terlalu antusias).

Saya tidak setuju.

Pertama-tama, semua yang lain mengatakan kepada Anda bahwa ini tidak ideal dan tidak benar-benar tenang benar. Dalam skenario RESTful yang tepat, Anda memanipulasi sumber daya di server dan menambahkan, memperbarui, menghapus, mengambil, dll sumber daya tersebut. PUT harus mengirim muatan yang mewakili sumber daya yang seharusnya ketika permintaan selesai, dan POST harus mengirim muatan yang mewakili sumber daya yang akan ditambahkan ke server. Dan GET harus mengembalikan sumber daya di server.

Anda memiliki RPC (panggilan prosedur jarak jauh), yang tidak tenang - Anda ingin MELAKUKAN sesuatu di server. Jadi, jika Anda mencoba membuat API murni TENANG, Anda harus mempertimbangkan kembali apa yang Anda lakukan.

Yang mengatakan, kadang-kadang Anda perlu sedikit membengkokkan aturan. Terutama jika Anda mengembangkan api internal yang tidak akan terekspos ke publik, Anda dapat memutuskan bahwa pertukaran itu sepadan.

Jika Anda melakukannya, saya akan merekomendasikan PUT atau POST, tergantung pada apakah RPC idempoten atau tidak.

Secara umum, kami mengatakan bahwa HTTP PUT memetakan ke SQL UPDATE dan HTTP POST memetakan ke SQL INSERT, tapi itu tidak sepenuhnya benar. Cara yang lebih murni untuk menyatakan bahwa HTTP PUT harus idempoten dan HTTP POST tidak perlu. Ini berarti bahwa Anda dapat memanggil permintaan PUT yang sama sebanyak yang Anda inginkan tanpa efek samping. Setelah Anda memanggilnya sekali, tidak berbahaya untuk menyebutnya lagi. Tetapi Anda tidak boleh berulang kali memanggil permintaan POST kecuali jika Anda bermaksud - setiap POST mengubah data di server lagi.

Dalam kasus Anda, jika Anda perlu memiliki fungsi memuat ulang ini, saya akan merekomendasikan PUT karena kedengarannya seperti idempoten. Tetapi saya masih mendesak Anda untuk mempertimbangkan apa yang dikatakan orang lain tentang tidak membutuhkannya sama sekali.

Aaron Greenwald
sumber
6

POSTdan PUTapakah kata kerja HTTP digunakan untuk mengirimkan entitas ke server web. Dengan PUT, entitas yang dikirimkan adalah representasi (baru) untuk sumber daya di URI yang diberikan, yang tidak sesuai dengan yang Anda inginkan. POSTadalah untuk form-handler tradisional, di mana entitas adalah data tambahan untuk sumber daya, jadi itulah pemenangnya. Entitas akan menyertakan perintah atau tindakan (mis. "Action = reload").

Yang mengatakan, perintah yang dimaksud mungkin tidak boleh diekspos melalui antarmuka REST. Kedengarannya seperti keharusan untuk "memuat kembali" muncul karena data dapat diubah melalui beberapa saluran lain (misalnya sistem file, klien DB). Tembolok harus transparan. Selain itu, permintaan HTTP harus bersifat atomik, bahkan mempertimbangkan pesan yang dikirim melalui saluran lain. Menawarkan perintah "muat ulang" untuk pengaturan konfigurasi tampaknya merupakan kompleksitas yang tidak perlu; membutuhkannya adalah desain yang rapuh. Mengekspos "reload" untuk dibersihkan setelah pembaruan melalui saluran lain kotor karena satu saluran tidak mengandung seluruh percakapan. Sebagai gantinya, pertimbangkan salah satu dari:

  • membuat pembaruan sepenuhnya melalui REST
  • mengekspos perintah ke saluran lain
  • mengotomatiskan tindakan

Beberapa opsi itu mungkin tidak dapat dijalankan, tergantung pada batasan apa yang ada.

Lihat juga " PUT vs POST di REST ".

outis
sumber
Terima kasih. Saya menghapus "internal" hasil edit karena sebenarnya metode "reload" dimaksudkan untuk umum. Saya hanya mencoba memaksudkan itu merujuk pada layanan web itu sendiri. Saya pikir memposting "tindakan" akan menjadi pendekatan yang baik.
Renato Dinhani
@ RenatoDinhaniConceição: bahkan tanpa "internal", masih berbau. Mungkin sebaiknya Anda mengajukan pertanyaan baru tentang apakah desainnya bagus.
outis
4

Saya akan berdebat mengapa permintaan klien secara eksplisit perlu membuat panggilan untuk menyegarkan sesuatu seperti itu. Kedengarannya seperti itu harus berupa logika tersembunyi pada implementasi GET yang lebih tipikal (yaitu, menarik data, tetapi layanan membuat penyegaran pada data sebelum ditarik), atau oleh pemicu lain di backend jauh dari klien.

Setelah semua, data / konfigurasi hanya perlu saat ini pada panggilan berikutnya, jadi saya akan lebih condong ke arah panggilan malas vs bersemangat untuk refresh data. Jelas saya berasumsi banyak di sini, tetapi saya akan mengambil langkah mundur untuk mengevaluasi kembali perlunya panggilan eksplisit dan mandiri.

Thomas Stringer
sumber
Lihatlah hasil edit saya. "reload" bukan perintah yang mengembalikan data. Ini merujuk pada layanan web REST itu sendiri. Secara umum, pertanyaan saya merujuk tentang memicu tindakan dalam layanan web REST. Contoh lain dapat berupa: email_queue/stop_sending_emails. Saya hanya memberi perintah untuk sesuatu menggunakan antarmuka yang tenang.
Renato Dinhani
5
Saya masih setuju. Menjalankan SIGHUP pada proses lokal masuk akal, karena komputer harus memercayai seseorang yang masuk secara lokal yang memiliki akses ke sinyal itu. Tetapi untuk protokol tanpa kewarganegaraan, akses Internet? Mungkin layanan web harus secara otomatis memuat kembali seperlunya melalui polling atau pemantauan file. Panggilan ini seharusnya sama sekali tidak perlu.
1
Saya setuju. Hal-hal seperti konfigurasi dan caching dimaksudkan untuk transparan kepada klien. Mungkin Anda harus memberi kami deskripsi yang lebih konkret tentang situasi di mana titik akhir Anda akan dipanggil.
Benjamin Hodgson
3

Mengapa tidak memperlakukan tindakan seperti sumber daya. Jadi karena Anda ingin memperbarui cache, Anda akan POST tindakan baru di sistem Anda.

Untuk pembuat puritan, Anda dapat memiliki url khusus untuk itu. Perhatikan bahwa Anda dapat memperluas ini dan mencatat tindakan aktual dalam database (atau penyimpanan apa pun) dengan tanggal, status, pengguna, dll. Hanya pemikiran saya di sini.

Operasi / tindakan / {aksi} di seluruh sistem generik

Operasi khusus untuk tipe sumber daya / tindakan / {sumber daya} / {aksi}

Operasi khusus untuk sumber daya / tindakan / {sumber daya} / {id} / {aksi}

Dalam kasus Anda, cache mungkin adalah sistem / action / reload_cache

Isometriq
sumber
0

Kata kerja HTTP mana yang harus saya gunakan untuk memicu tindakan di layanan web REST?

Saat mempertimbangkan detail layanan REST, sering kali bermanfaat untuk mempertimbangkan heuristik ini: bagaimana Anda mengimplementasikannya dengan situs web?

HTML hanya dapat menggambarkan secara alami permintaan GET dan POST. Jadi kita bisa mulai mencari di sana.

Apakah GETpantas? Untuk menjawab pertanyaan ini, kita perlu memikirkan asumsi bahwa klien dan komponen perantara diperbolehkan membuat GET. Semantik GETyang aman

klien tidak meminta, dan tidak mengharapkan, perubahan apa pun pada server asal sebagai hasil dari penerapan metode aman ke sumber daya target. Demikian juga, penggunaan metode aman yang wajar tidak diharapkan dapat menyebabkan kerugian, kehilangan properti, atau beban yang tidak biasa pada server asal.

Implikasinya, oleh karena itu, adalah bahwa klien dan komponen perantara memiliki keleluasaan untuk memohon permintaan GET sesering yang diperlukan untuk memuaskan kekhawatiran mereka sendiri. Laba-laba dapat MENDAPATKAN sumber daya tanpa pandang bulu untuk memperbarui indeks mereka. Tembolok dapat diambil sebelumnya. Pada jaringan yang tidak dapat diandalkan, pesan yang hilang dapat dicoba sesering mungkin untuk memastikan setidaknya satu tanggapan.

Ini akan digunakan untuk memuat ulang konfigurasi, cache, dll.

Jika ini adalah hal-hal mahal yang harus dilakukan, maka mungkin Anda tidak ingin klien mengeluarkan permintaan ini atas kebijakan mereka sendiri.

POST, di sisi lain, secara efektif tidak dibatasi - ini sangat mengurangi asumsi bahwa klien generik diperbolehkan membuat. Anda tidak mendapatkan komponen yang membuat permintaan POST spekulatif karena mereka akan salah melakukannya - tidak ada dalam standar yang mengatakan tidak apa-apa.

PUT, PATCH, DELETE... ini adalah metode yang tidak aman dengan semantik lebih spesifik dari POST; apakah mereka sesuai atau tidak akan tergantung pada model sumber daya Anda.

Gagasan penting yang perlu diingat adalah bahwa metode HTTP termasuk dalam domain dokumen (Lihat ceramah Jim Webber 2011 ), efek yang Anda uraikan mungkin bukan bagian dari domain dokumen, melainkan efek samping yang dipanggil ketika dokumen diubah . Itu memberi Anda banyak kebebasan dalam hal bagaimana Anda mengatur dokumen Anda untuk menyelesaikan pekerjaan.

VoiceOfUnreason
sumber