Bagaimana cara pencarian masuk ke antarmuka RESTful?

137

Saat mendesain antarmuka RESTful, semantik dari tipe permintaan dianggap penting untuk desain.

  • DAPATKAN - Daftar koleksi atau ambil elemen
  • PUT - Ganti koleksi atau elemen
  • POST - Buat koleksi atau elemen
  • HAPUS - Ya, erm, hapus koleksi atau elemen

Namun, ini sepertinya tidak mencakup konsep "pencarian".

Misalnya dalam mendesain rangkaian layanan web yang mendukung situs Pencarian Kerja, Anda mungkin memiliki persyaratan berikut:

  • Dapatkan Iklan Pekerjaan individual
    • GET kedomain/Job/{id}/
  • Buat Iklan Pekerjaan
    • POST kedomain/Job/
  • Perbarui Iklan Pekerjaan
    • PUT kedomain/Job/
  • Hapus Iklan Pekerjaan
    • HAPUS kedomain/Job/

"Dapatkan Semua Pekerjaan" juga sederhana:

  • GET kedomain/Jobs/

Namun, bagaimana pekerjaan "pencarian" jatuh ke dalam struktur ini?

Anda dapat mengklaim itu adalah variasi "koleksi daftar" dan terapkan sebagai:

  • GET kedomain/Jobs/

Namun, pencarian bisa rumit dan sangat mungkin untuk menghasilkan pencarian yang menghasilkan string GET panjang. Artinya, merujuk pertanyaan SO di sini , ada masalah menggunakan string GET lebih lama dari sekitar 2000 karakter.

Contoh mungkin dalam pencarian faceted - melanjutkan contoh "pekerjaan".

Saya dapat mengizinkan untuk mencari di aspek - "Teknologi", "Judul Pekerjaan", "Disiplin" serta kata kunci teks bebas, usia pekerjaan, lokasi dan gaji.

Dengan antarmuka pengguna yang lancar dan sejumlah besar teknologi dan jabatan, layak dilakukan pencarian yang dapat mencakup sejumlah besar pilihan segi.

Tweak contoh ini ke CV, daripada pekerjaan, membawa lebih banyak aspek, dan Anda dapat dengan mudah membayangkan pencarian dengan seratus aspek yang dipilih, atau bahkan hanya 40 aspek yang masing-masing terdiri dari 50 karakter (misalnya Judul Pekerjaan, Nama Universitas, Nama Pemberi Kerja).

Dalam situasi itu mungkin diinginkan untuk memindahkan PUT atau POST untuk memastikan bahwa data pencarian akan dikirim dengan benar. Misalnya:

  • POST kedomain/Jobs/

Namun secara semantik itu adalah instruksi untuk membuat koleksi.

Anda juga bisa mengatakan Anda akan mengungkapkan ini sebagai kreasi pencarian:

  • POST kedomain/Jobs/Search/

atau (seperti yang disarankan oleh burninggramma di bawah)

  • POST kedomain/JobSearch/

Semantik mungkin masuk akal, tetapi Anda tidak benar-benar membuat apa-apa, Anda membuat permintaan untuk data.

Jadi, semantik GET , tetapi GET tidak dijamin untuk mendukung apa yang Anda butuhkan.

Jadi, pertanyaannya adalah - Berusaha untuk tetap setia pada desain RESTful mungkin, sambil memastikan bahwa saya tetap dalam batasan HTTP, apa desain yang paling tepat untuk pencarian?

Rob Baillie
sumber
3
Saya sering berniat menggunakan GET domain/Jobs?keyword={keyword} . Ini berfungsi dengan baik untuk saya :) Harapan saya adalah, bahwa SEARCHkata kerja akan menjadi standar. programmers.stackexchange.com/questions/233158/…
Knerd
Ya, saya bisa melihat bahwa untuk contoh sepele tidak ada masalah. Namun dalam alat yang kami buat itu sebenarnya tidak terlalu sulit dipercaya bahwa kami akan berakhir dengan pencarian kompleks yang menghasilkan string GET lebih dari 2000 karakter. Lalu bagaimana?
Rob Baillie
Sebenarnya poin yang sangat bagus. Bagaimana dengan menentukan teknologi kompresi?
Knerd
2
DAPATKAN dengan badan diizinkan oleh spec HTTP, mungkin atau mungkin tidak didukung oleh middleware (kadang-kadang tidak);) dan tidak disukai sebagai praktik. Ini muncul di Stackexchange secara berkala. stackoverflow.com/questions/978061/http-get-with-request-body
Rob
2
Saya akhirnya meminta POST JobSearch membuat entitas pencarian yang sebenarnya dan mengembalikan jobSearchId. Kemudian DAPATKAN pekerjaan? JobSearch = jobSearchId mengembalikan koleksi pekerjaan yang sebenarnya.
Cerad

Jawaban:

93

Anda jangan lupa bahwa permintaan GET memiliki beberapa keunggulan unggul dibandingkan solusi lain:

1) Permintaan GET dapat disalin dari bilah URL, mereka dicerna oleh mesin pencari, mereka "ramah". Di mana "ramah" berarti bahwa biasanya permintaan GET tidak boleh mengubah apa pun di dalam aplikasi Anda (idempoten) . Ini adalah kasus standar untuk pencarian.

2) Semua konsep ini sangat penting tidak hanya dari pengguna dan mesin pencari, tetapi dari sudut pandang arsitektur, desain API .

3) Jika Anda membuat solusi dengan POST / PUT Anda akan memiliki masalah yang tidak Anda pikirkan saat ini. Misalnya dalam hal browser tombol navigasi kembali / refresh halaman / riwayat. Ini bisa dipecahkan tentu saja, tapi itu akan menjadi solusi lain, lalu yang lain dan yang lain ...

Mempertimbangkan semua ini, saran saya adalah:

a) Anda harus bisa masuk ke dalam GET Anda dengan menggunakan struktur parameter pintar . Dalam kasus ekstrim Anda bahkan dapat menggunakan taktik seperti pencarian google ini di mana saya mengatur banyak parameter masih url super pendek.

b) Buat entitas lain di aplikasi Anda seperti JobSearch . Dengan asumsi Anda punya begitu banyak pilihan, kemungkinan Anda perlu menyimpan pencarian ini juga dan mengelolanya, jadi itu hanya membersihkan aplikasi Anda. Anda dapat bekerja dengan objek JobSearch secara keseluruhan, artinya Anda dapat mengujinya / menggunakannya dengan lebih mudah .


Secara pribadi saya akan mencoba untuk bertarung dengan semua cakar saya untuk menyelesaikannya dengan a) dan ketika semua harapan hilang, saya akan merangkak kembali dengan air mata di mata saya ke opsi b) .

p1100i
sumber
4
Untuk klarifikasi, pertanyaan ini dimaksudkan tentang desain layanan web, bukan desain situs web. Jadi, sementara perilaku browser menarik dalam cakupan interpretasi pertanyaan yang lebih luas, dalam kasus khusus yang dijelaskan itu tidak ada konsekuensinya. (titik yang menarik).
Rob Baillie
@RobBaillie Kamu browser ini hanya kasus penggunaan. Saya ingin mengungkapkan fakta bahwa pencarian Anda secara keseluruhan diwakili oleh string URL. Yang memiliki banyak kenyamanan dalam kegunaan bersama dengan poin lain nanti dalam jawabannya.
p1100i
Dalam huruf b, apakah ini variasi sederhana dari referensi saya sendiri untuk POST untuk domain/Jobs/Search/, mungkin dengan domain/JobsSearch/sebaliknya, atau apakah Anda berarti sesuatu yang berbeda? Bisakah Anda mengklarifikasi?
Rob Baillie
7
Mengapa saya mendapat kesan bahwa REST sering merupakan bagian dari masalah, bukan bagian dari solusi?
JensG
1
"Permintaan GET tidak boleh memodifikasi apa pun di dalam aplikasi Anda (idempoten)" sementara GET idempoten, kata yang relevan adalah " aman " di sini. Idempoten berarti melakukan GET pada sumber daya dua kali sama dengan melakukan GET pada sumber daya itu sekali. PUT juga idempoten, tetapi tidak aman, misalnya.
Jasmijn
12

TL; DR: DAPATKAN untuk pemfilteran, POST untuk pencarian

Saya membuat perbedaan antara memfilter hasil dari daftar koleksi vs pencarian yang kompleks. Tes lakmus yang saya gunakan pada dasarnya adalah jika saya membutuhkan lebih dari penyaringan (positif, negatif, atau kisaran) Saya menganggapnya sebagai pencarian yang lebih kompleks yang membutuhkan POST.

Ini cenderung diperkuat ketika memikirkan apa yang akan dikembalikan. Saya biasanya hanya menggunakan GET jika sumber daya memiliki sebagian besar siklus hidup lengkap (PUT, DELETE, GET, collection GET) . Biasanya dalam koleksi DAPATKAN saya mengembalikan daftar URI yang merupakan sumber daya REST yang membentuk koleksi itu. Dalam kueri yang kompleks, saya mungkin menarik dari banyak sumber daya untuk membangun respons (pikirkan SQL join) jadi saya tidak akan mengirim kembali URI, tetapi data aktual. Masalahnya adalah data tidak akan diwakili dalam sumber daya, jadi saya harus selalu mengembalikan data. Bagi saya ini adalah kasus yang jelas membutuhkan POST.

-

Sudah beberapa saat dan posting asli saya agak ceroboh jadi saya pikir saya akan memperbarui.

GET adalah pilihan intuitif untuk mengembalikan sebagian besar jenis data, koleksi sumber daya REST, data terstruktur sumber daya, bahkan muatan tunggal (gambar, dokumen, dll).

POST adalah metode catchall untuk apa pun yang tampaknya tidak sesuai dengan GET, PUT, DELETE, dll.

Pada titik ini saya pikir pencarian sederhana, pemfilteran secara intuitif masuk akal melalui GET. Pencarian kompleks tergantung pada preferensi pribadi terutama jika Anda melempar fungsi agregasi, korelasi silang (bergabung), format ulang, dll. Saya berpendapat bahwa par GET tidak boleh terlalu lama, dan itu adalah permintaan yang banyak (namun sedang disusun ) sering lebih masuk akal sebagai badan permintaan POST.

Saya juga mempertimbangkan aspek pengalaman penggunaan API. Saya umumnya ingin membuat sebagian besar metode semudah digunakan dan intuitif mungkin. Saya akan mendorong panggilan yang lebih fleksibel (dan karenanya lebih kompleks) ke dalam POST dan pada URI sumber daya yang berbeda, terutama jika itu tidak konsisten dengan perilaku sumber daya REST lainnya di API yang sama.

Either way, konsistensi mungkin lebih penting daripada apakah Anda melakukan pencarian di GET atau POST.

Semoga ini membantu.

dietbuddha
sumber
1
Karena REST dimaksudkan untuk mengabstraksi implementasi yang mendasarinya (mis. - sumber daya tidak selalu berupa baris dalam database atau file pada hard drive, tetapi bisa berupa apa saja ) Saya tidak tahu bahwa perlu untuk menggunakan POST secara masuk akal. DAPATKAN ketika melakukan SQL join. Misalkan Anda memiliki tabel sekolah dan tabel anak-anak dan Anda menginginkan kelas (satu sekolah, banyak anak). Anda dapat dengan mudah menentukan sumber daya virtual dan GET /class?queryParams. Dari perspektif pengguna, "kelas" selalu merupakan hal dan Anda tidak perlu melakukan penggabungan SQL yang aneh.
stevendesu
Tidak ada perbedaan antara "pemfilteran" dan "pencarian".
Nicholas Shanks
1
Ya ada, filter didasarkan pada bidang yang ada. Pencarian mungkin mengandung pola yang jauh lebih kompleks, menggabungkan bidang, menghitung nilai
adjecent
@stevendesu tepatnya, itu sebabnya saya menggunakan POST untuk keduanya (membuat pencarian) :-)
ymajoros
@ymajoros Kecuali jika Anda menyimpan istilah pencarian dan hasil pencarian di suatu tempat, saya tidak tahu bahwa POST masuk akal secara semantik. Ketika Anda melakukan pencarian, Anda meminta informasi, Anda tidak memberikan informasi baru untuk disimpan di mana pun.
stevendesu
10

Dalam REST, definisi sumber daya sangat luas. Namun sebenarnya Anda ingin menggabungkan beberapa data.

  • Sangat berguna untuk memikirkan sumber pencarian sebagai sumber koleksi. Parameter kueri, kadang-kadang disebut bagian yang dapat dicari dari URI, mempersempit sumber daya ke item yang diminati klien.

Misalnya, Google URI utama menunjuk ke sumber daya koleksi "tautan ke setiap situs di Internet". Parameter kueri mempersempitnya ke situs yang ingin Anda lihat.

(URI = pengidentifikasi sumber daya universal, yang URL = pencari sumber daya universal, di mana "http: //" yang familier adalah format default untuk URI. Jadi URL adalah pelacak, tetapi di REST ada baiknya menggeneralisasikannya ke pengenal sumber daya Namun, orang-orang menggunakannya secara bergantian.)

  • Karena sumber daya yang Anda cari dalam contoh Anda adalah kumpulan pekerjaan, masuk akal untuk mencari

DAPATKAN situs / pekerjaan? Ketik = bla & lokasi = di sini & dll = dll

(kembali) {jobs: [{job: ...}]}

Dan kemudian gunakan POST, yang merupakan append atau kata kerja proses untuk menambahkan item baru ke koleksi itu:

Situs / pekerjaan POST

{job: ...}

  • Perhatikan bahwa itu adalah struktur yang sama untuk jobobjek dalam setiap kasus. Seorang klien dapat DAPATKAN kumpulan pekerjaan, menggunakan params pertanyaan untuk mempersempit pencarian, dan kemudian menggunakan format yang sama untuk salah satu item untuk POST pekerjaan baru. Atau dapat mengambil salah satu item dan PUT ke URI untuk memperbarui yang itu.

  • Untuk string kueri yang sangat panjang atau rumit, konvensi membuat OK untuk mengirimnya sebagai permintaan POST. Bundel parameter kueri ke atas sebagai pasangan nama / nilai, atau objek bersarang di struktur JSON atau XML dan kirim ke badan permintaan. Misalnya, jika kueri Anda memiliki data bersarang alih-alih sekelompok pasangan nama / nilai. HTTP spec untuk POST menggambarkannya sebagai append atau kata kerja proses. (Jika Anda ingin berlayar kapal perang melalui celah di REST, gunakan POST.)

Saya akan menggunakannya sebagai rencana fallback.

Apa yang Anda kehilangan ketika Anda melakukan itu adalah a) GET adalah nullipotent - artinya, tidak mengubah apa pun - POST tidak. Jadi jika panggilan gagal, middleware tidak akan secara otomatis mencoba kembali atau menyimpan hasil, dan 2) dengan parameter pencarian di tubuh, Anda tidak dapat memotong dan menempelkan URI lagi. Artinya, URI bukan pengidentifikasi khusus untuk pencarian yang Anda inginkan.

Untuk membedakan antara "buat" dari "pencarian". Ada beberapa opsi yang konsisten dengan praktik REST:

  • Anda bisa melakukannya di URI dengan menambahkan sesuatu ke nama koleksi, seperti mencari pekerjaan dan bukan pekerjaan. Itu hanya berarti Anda memperlakukan koleksi pencarian sebagai sumber daya yang terpisah.

  • Karena semantik POST sama-sama menambahkan proses ATAU, Anda dapat mengidentifikasi badan pencarian dengan muatan. Seperti {job: ...} vs. {search: ...}. Terserah logika POST untuk memposting atau memprosesnya dengan tepat.

Itu cukup banyak preferensi desain / implementasi. Saya tidak berpikir ada konvensi yang jelas.

Jadi, seperti yang sudah Anda paparkan, idenya adalah untuk menentukan sumber daya koleksi jobs

situs / pekerjaan

Cari dengan GET + permintaan params untuk mempersempit pencarian. Kueri data yang panjang atau terstruktur masuk ke tubuh POST (mungkin ke koleksi pencarian terpisah). Buat dengan POST untuk menambahkan ke koleksi. Dan perbarui dengan PUT ke URI tertentu.

(FWIW konvensi gaya dengan URI adalah menggunakan semua huruf kecil dengan kata-kata yang dipisahkan oleh tanda hubung. Tapi itu tidak berarti Anda harus melakukannya dengan cara itu.)

(Juga, saya harus mengatakan itu dari pertanyaan Anda, sudah jelas bahwa Anda berada jauh di jalan ini. Saya menjabarkan hal-hal secara eksplisit hanya untuk mengatur mereka, tetapi pertanyaan Anda telah membahas sebagian besar masalah semantik dalam hal ini). jawaban. Saya hanya mengaitkannya dengan beberapa konvensi dan latihan.)

rampok
sumber
Itu ide yang menarik - saya tidak akan mempertimbangkan menggunakan payload untuk membedakan. Tampaknya agak licik! Tapi saya kira skema URI tidak benar-benar mengandung kata kerja - itu jenis permintaan yang mendefinisikan kata kerja. Mungkin payload lebih dekat secara semantik dengan tipe permintaan daripada URI. Satu-satunya masalah adalah - Apakah transparan untuk pengguna API?
Rob Baillie
Dalam hal implementasi (kami menggunakan Node dan Express), itu mungkin berarti mereka routetidak bisa menangani pilihan pemrosesan. Saya harus melihat itu ...
Rob Baillie
Saya memiliki perasaan yang sama, bahwa memisahkannya dengan URI tampaknya lebih bersih. Aku agak bolak-balik; itu panggilan penghakiman. Namun, semantik HTTP akan memungkinkan memasukkannya ke dalam tubuh. Saya suka mengatakan, REST dimodelkan setelah World Wide Web, dan WWW dibangun dengan GET dan POST.
Rob
8

Saya biasanya menggunakan query OData, mereka beroperasi sebagai panggilan GET tetapi memungkinkan Anda untuk membatasi properti yang dikembalikan dan menyaringnya.

Anda menggunakan token seperti $select=dan $filter=Anda akan berakhir dengan URI yang terlihat seperti ini:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

Anda juga dapat melakukan paging menggunakan $skipdan $topdan pemesanan.

Untuk informasi lebih lanjut, lihat OData.org . Anda belum menentukan bahasa yang Anda gunakan, tetapi jika itu ASP.NET, platform WebApi mendukung permintaan OData - untuk yang lain (PHP dll) mungkin ada perpustakaan yang dapat Anda gunakan untuk menerjemahkannya ke dalam kueri basis data.

Trevor Pilley
sumber
6
Tautan yang menarik dan layak dilihat, tetapi apakah itu menyelesaikan masalah mendasar yang dijelaskan, bahwa permintaan GET tidak mendukung lebih dari 2000 karakter dalam string kueri, dan sangat mungkin bahwa kueri bisa jauh lebih lama dari ini?
Rob Baillie
@RobBaillie Saya tidak berpikir begitu karena masih berupa panggilan GET dengan string kueri. Saya sarankan menggunakan OData di mana pun Anda bisa karena ini merupakan standar untuk kueri sumber data web dan untuk beberapa (jika ada) kali kueri harus sangat kompleks sehingga Anda tidak dapat memasukkannya dalam kueri 2000 karakter, buat spesifik titik akhir tempat Anda melakukan panggilan GET ke
Trevor Pilley
Bisakah Anda menjelaskan pendekatan Anda untuk "titik akhir spesifik tempat Anda melakukan panggilan GET"? Bagaimana Anda bisa membayangkan titik akhir itu akan terlihat?
Rob Baillie
@RobBaillie yakin - sekali lagi saya tidak yakin apa teknologi yang Anda gunakan tetapi dalam ASP.NET saya akan membuat controller spesifik yang disebut JobsNearMeAddedInTheLast7Daysatau apa pun untuk merangkum permintaan yang terlalu panjang / kompleks untuk OData dan kemudian memaparkannya hanya melalui panggilan GET .
Trevor Pilley
1
Saya melihat. Pikiran lain yang menarik yang mungkin memiliki beberapa kaki, meskipun saya tidak yakin ini akan membantu dalam kasus khusus saya - pencarian faceted dengan banyak jenis facet dan banyak kemungkinan nilai facet
Rob Baillie
5

Satu pendekatan untuk dipertimbangkan adalah memperlakukan set kueri yang mungkin sebagai sumber daya pengumpulan, misalnya /jobs/filters.

POSTpermintaan untuk sumber daya ini, dengan parameter permintaan dalam tubuh, baik akan menciptakan sumber daya baru atau mengidentifikasi ada setara filter dan mengembalikan URL yang berisi ID nya: /jobs/filters/12345.

Id kemudian dapat digunakan dalam permintaan GET untuk pekerjaan: /jobs?filter=12345. GETPermintaan selanjutnya pada sumber daya filter akan mengembalikan definisi filter.

Pendekatan ini memiliki keuntungan yang membebaskan Anda dari format parameter kueri untuk definisi filter, berpotensi memberi Anda lebih banyak kekuatan untuk mendefinisikan filter kompleks. ATAU kondisi adalah salah satu contoh yang dapat saya pikirkan yang sulit dicapai dengan string kueri.

Kelemahan dari pendekatan ini adalah Anda kehilangan keterbacaan URL (meskipun ini dapat mengurangi dengan mengambil definisi melalui GETpermintaan untuk sumber daya filter). Untuk alasan ini, Anda mungkin juga ingin mendukung yang sama atau subset dari parameter kueri pada /jobssumber daya seperti yang Anda dukung untuk sumber daya filter. Ini bisa digunakan untuk kueri yang lebih pendek. Jika fitur ini disediakan, untuk mempertahankan cacheability antara dua jenis penyaringan, ketika menggunakan parameter query pada /jobssumber daya, pelaksanaan harus internal membuat / menggunakan kembali sumber daya filter dan mengembalikan 302atau 303status yang menunjukkan URL dalam bentuk /jobs?filter=12345.

pgraham
sumber
Reaksi pertama saya terhadap hal ini adalah bahwa walaupun ini adalah informasi yang baik, itu benar-benar hanya variasi pada jawaban yang diberikan oleh @burninggramma. Pada dasarnya itu adalah "buat entitas baru yang disebut filter / pencarian, panggil untuk membuatnya dan kemudian panggil untuk mengambilnya". Variasi adalah bahwa panggilan untuk mengambilnya lebih mirip panggilan untuk menerapkannya ke koleksi. Menarik. Namun jawaban Anda dan burninggramma menderita masalah yang sama - Saya tidak punya keinginan untuk membuat filter. Akan ada sejumlah besar dari mereka, dan mereka tidak perlu disimpan kecuali untuk menjaga implementasi yang tenang.
Rob Baillie
2
Jelas, parameter kueri adalah solusi terbaik, tetapi pertanyaan Anda secara khusus bertanya tentang bagaimana menangani definisi filter lebih lama dari batas pada URL yang diberlakukan oleh beberapa server. Untuk mengatasi batas panjang, Anda harus memampatkan string kueri entah bagaimana atau Anda perlu menggunakan metode permintaan yang mendukung menentukan badan dengan panjang sewenang-wenang. Jika Anda tidak ingin memperlakukan filter sebagai sumber daya, cukup dukung antarmuka yang tidak tenang di mana definisi filter diposkan. Anda akan kehilangan cacheability, tetapi jika data Anda cukup mudah menguap itu tidak akan mendapat manfaat dari caching.
pgraham
Anda dapat mengatasi kebutuhan untuk menyimpan filter hanya dengan ... tidak menyimpannya. Tidak ada apa pun tentang REST yang menjamin bahwa itu persisten. Anda mungkin membuat permintaan GET /jobs/37dan menerima hasil, kemudian seseorang menghapus sumber daya dan 2 detik kemudian permintaan yang sama mengembalikan 404. Demikian pula jika Anda POST /searchesdan Anda diarahkan ke hasil pencarian (pencarian dibuat dan Anda menerima 201 dengan Header lokasi ke sumber daya), 2 detik kemudian hasil itu dapat dihapus dari memori dan harus dibuat ulang. Tidak perlu penyimpanan jangka panjang.
stevendesu
5

Ini adalah jawaban lama tapi saya masih bisa berkontribusi sedikit untuk diskusi. Saya sering mengamati kesalahpahaman tentang REST, RESTful, dan Architecture. RESTful tidak pernah menyebutkan apapun tentang TIDAK membangun pencarian, tidak ada dalam RESTful tentang arsitektur, itu adalah seperangkat prinsip atau kriteria desain.

Untuk menggambarkan Pencarian dengan cara yang lebih baik, kita harus berbicara tentang arsitektur khususnya dan yang lebih cocok adalah Arsitektur Berorientasi Sumber Daya (ROA).

Dalam RESTful ada prinsip untuk mendesain, idempoten tidak berarti hasilnya tidak dapat berubah ketika saya membaca dalam beberapa jawaban, itu berarti hasil dari permintaan independen tidak tergantung pada berapa kali dieksekusi. Itu bisa berubah, mari kita bayangkan saya terus memperbarui basis data yang memberinya dengan beberapa data yang dilayani oleh RESTful Api, mengeksekusi GET yang sama mungkin mengubah hasilnya tetapi tidak tergantung pada berapa kali dieksekusi. Jika saya dapat membekukan dunia itu berarti tidak ada keadaan, transformasi, apa pun di dalam layanan ketika saya meminta sumber daya yang mengarah ke hasil yang berbeda.

Menurut definisi, sumber daya adalah segala sesuatu yang penting untuk dirujuk sebagai sesuatu dengan sendirinya.

Dalam arsitektur berorientasi sumber daya (sebut saja ROA mulai sekarang untuk singkatnya) kami fokus pada sumber daya yang bisa menjadi banyak hal:

  • Versi dokumen
  • Versi dokumen yang terakhir diperbarui
  • Hasil yang berasal dari pencarian
  • Daftar benda
  • Artikel pertama yang saya beli dari e-commerce

Apa yang membuatnya unik dalam hal sumber daya adalah addresability yang berarti hanya memiliki satu URI

Dengan cara itu pencarian sangat cocok di RESTful mempertimbangkan ROA . Kami harus menggunakan GET karena saya menganggap pencarian Anda adalah pencarian normal dan tidak mengubah apa pun, jadi idempoten (bahkan jika mengembalikan hal yang berbeda tergantung pada elemen baru yang ditambahkan). Ada kebingungan di sini dengan cara itu karena saya bisa tetap pada RESTful dan tidak ke ROA, itu berarti saya bisa mengikuti pola yang menciptakan pencarian dan mengembalikan hal-hal yang berbeda dengan parameter yang sama karena saya tidak menggunakan prinsip addressability dari ROA. Bagaimana itu? Nah, jika Anda mengirim filter pencarian di badan atau header sumber daya tidak ADDRESSABLE.

Anda dapat menemukan prinsip-prinsip apa yang sebenarnya dan URI dalam dokumen asli W3:

https://www.w3.org/DesignIssues/Axioms

Setiap URL dalam arsitektur ini harus bersifat deskriptif sendiri. Ini penting jika Anda mengikuti prinsip untuk mengatasi semua yang ada di URI, itu artinya Anda dapat menggunakan / (memangkas) untuk memisahkan apa pun yang Anda butuhkan atau parameter kueri. Kita tahu ada batasan untuk itu tetapi ini adalah pola arsitekturnya.

Mengikuti pola ROA di RESTful pencarian tidak lebih dari sumber daya lainnya, satu-satunya perbedaan adalah sumber daya berasal dari perhitungan, bukan dari hubungan langsung ke objek itu sendiri. Berdasarkan prinsip saya dapat membahas dan mendapatkan layanan perhitungan aritmatika sederhana berdasarkan pola berikut:

http://myapi.com/sum/1/2

Di mana jumlah, 1 dan 2 dapat dimodifikasi tetapi hasil perhitungannya unik dan sangat menarik, setiap kali saya menelepon dengan parameter yang sama, saya mendapatkan perubahan yang sama dan tidak ada perubahan dalam layanan. Sumber / jumlah / 1/2 dan / pengurangan / 5/4 berpegang teguh pada prinsip-prinsip dengan sempurna.

Maximiliano Rios
sumber
3

GET tidak masalah, jika Anda memiliki koleksi statis yang selalu mengembalikan hasil yang sama (representasi) untuk satu URI. Itu juga menyiratkan bahwa data yang menghasilkan representasi ini tidak pernah diubah. Sumbernya adalah database hanya-baca.

Memiliki GET mengembalikan hasil yang berbeda untuk satu dan URI yang sama melanggar idempotensi / keselamatan dan prinsip CoolURI dan akibatnya tidak tenang . Dimungkinkan untuk memiliki kata kerja idempoten menulis ke database, tetapi mereka tidak boleh mempengaruhi representasi.

Pencarian umum dimulai dengan permintaan POST yang mengembalikan referensi ke hasilnya. Ini menghasilkan hasilnya (ini baru dan dapat diambil dengan GET berikutnya). Hasil ini dapat bersifat hierarkis (referensi lebih lanjut dengan URI yang dapat Anda DAPATKAN), tentu saja, dan mungkin menggunakan kembali elemen pencarian sebelumnya, jika masuk akal untuk aplikasi tersebut.

Ngomong-ngomong, saya tahu orang melakukannya secara berbeda. Anda tidak perlu menjelaskan kepada saya betapa mudahnya melanggar REST.

Martin Sugioarto
sumber
Aaaaaaaah - jadi begitulah seharusnya bekerja! Terima kasih!
Rob Baillie
1
Idempotensi tidak berarti ia harus selalu kembali persis sama, ia harus kembali sama jika TIDAK ADA perubahan. Pencarian dapat dianggap sebagai hasil perhitungan dan itu adalah sumber daya itu sendiri.
Maximiliano Rios
Idempotensi sebenarnya TIDAK berarti hasil tetap sama. Anda dapat, dan praktis, untuk menggunakan kontrol cache. Dan tentu saja Anda dapat menggunakan DELETE yang mengganggu GET nantinya. Namun, jika seorang agen perlu menyimpan pengetahuan tentang cara kerja aplikasi, itu tidak tenang lagi. Di atas, saya berbicara tentang ide REST yang paling ekstrem. Dalam praktiknya, orang bisa melanggar banyak aspek. Mereka membayar harganya ketika cache tidak lagi melakukan cache secara efisien.
Martin Sugioarto
"Idempotensi sebenarnya TIDAK berarti hasilnya tetap sama." ... setelah permintaan. intinya, saya percaya, permintaan itu tidak mengubah data.
AndreiMotinga