Saya perlu merancang API permintaan RESTful, yang mengembalikan satu set objek berdasarkan beberapa filter. Metode HTTP biasa untuk ini adalah GET. Satu-satunya masalah adalah, ia dapat memiliki setidaknya selusin filter, dan jika kita melewatkan semuanya sebagai parameter kueri, URL bisa menjadi cukup lama (cukup lama untuk diblokir oleh beberapa firewall).
Mengurangi jumlah parameter bukanlah suatu pilihan.
Salah satu alternatif yang dapat saya pikirkan adalah memanfaatkan metode POST pada URI dan mengirim filter sebagai bagian dari badan POST. Apakah ini bertentangan dengan RESTfull (Melakukan panggilan POST untuk meminta data).
Adakah yang punya saran desain yang lebih baik?
api
rest
http-parameters
missionE46
sumber
sumber
Jawaban:
Ingat bahwa dengan API REST, itu semua adalah pertanyaan tentang sudut pandang Anda.
Dua konsep utama dalam REST API adalah titik akhir dan sumber daya (entitas). Secara longgar, endpoint mengembalikan sumber daya melalui GET atau menerima sumber daya melalui POST dan PUT dan sebagainya (atau kombinasi dari yang di atas).
Diterima bahwa dengan POST, data yang Anda kirim dapat atau tidak dapat mengakibatkan penciptaan sumber daya baru dan titik akhir yang terkait, yang kemungkinan besar tidak akan "hidup" di bawah url POSTed. Dengan kata lain ketika Anda POST Anda mengirim data ke suatu tempat untuk penanganan. Titik akhir POST bukanlah tempat sumber daya biasanya ditemukan.
Mengutip dari RFC 2616 (dengan bagian yang tidak relevan dihilangkan, dan bagian yang relevan disorot):
Kami telah terbiasa dengan titik akhir dan sumber daya yang mewakili 'barang' atau 'data', baik itu pengguna, pesan, buku - apa pun yang ditentukan domain masalah. Namun, titik akhir juga dapat mengekspos sumber daya yang berbeda - misalnya hasil pencarian.
Perhatikan contoh berikut:
Ini adalah CREST REST tipikal. Namun bagaimana jika kami menambahkan:
Tidak ada yang tenang tentang titik akhir ini. Ia menerima data (entitas) dalam bentuk badan permintaan. Data itu adalah Kriteria Pencarian - DTO seperti yang lain. Titik akhir ini menghasilkan sumber daya (entitas) dalam menanggapi permintaan: Hasil Pencarian . Sumber daya hasil pencarian bersifat sementara, disajikan segera kepada klien, tanpa arahan ulang, dan tanpa terkena dari beberapa url kanonik lainnya.
Itu masih REST, kecuali entitas bukan buku - entitas permintaan adalah kriteria pencarian buku, dan entitas respons adalah hasil pencarian buku.
sumber
BooksSearchCriteriaDTO
danBooksSearchResultsDTO
.POST
digunakan untuk bagian C dari CRUD. Saya akan menggunakan 200, yang mungkin opsional dengan 204 untuk hasil pencarian kosong.Banyak orang telah menerima praktik bahwa GET dengan string kueri yang terlalu panjang atau terlalu rumit (mis. String kueri tidak mudah menangani data bersarang) dapat dikirim sebagai POST, dengan data kompleks / panjang terwakili dalam tubuh dari permintaan.
Cari spec untuk POST di spec HTTP. Ini sangat luas. (Jika Anda ingin berlayar kapal perang melalui celah di REST ... gunakan POST.)
Anda kehilangan beberapa manfaat dari semantik GET ... seperti coba ulang otomatis karena GET idempoten, tetapi jika Anda dapat hidup dengan itu, mungkin lebih mudah untuk hanya menerima pemrosesan pertanyaan yang sangat panjang atau rumit dengan POST.
(lol penyimpangan panjang ... Saya baru-baru ini menemukan bahwa dengan spec HTTP, GET dapat berisi badan dokumen. Ada satu bagian yang mengatakan, parafrase, "Permintaan apa pun dapat memiliki badan dokumen kecuali yang terdaftar di bagian ini" ... dan bagian yang dimaksud tidak mencantumkan apa pun. Saya mencari dan menemukan utas di mana penulis HTTP membicarakan hal itu, dan itu disengaja, sehingga router dan semacamnya tidak perlu membedakan antara pesan yang berbeda. berlatih banyak potongan infrastruktur yang menjatuhkan tubuh GET. Jadi Anda bisa MENDAPATKAN dengan filter yang terwakili dalam tubuh, seperti POST, tetapi Anda akan menggulirkan dadu.)
sumber
Singkatnya: Buat POST tetapi timpa metode HTTP menggunakan header X-HTTP-Method-Override .
Permintaan nyata
POST / buku
Badan entitas
{"title": "Ipsum", "year": 2017}
Tajuk
X-HTTP-Method-Override: GET
Di sisi server, periksa apakah header X-HTTP-Method-Override ada kemudian ambil nilainya sebagai metode untuk membangun rute ke titik akhir akhir di backend. Juga, ambil badan entitas sebagai string kueri. Dari sudut pandang backend, permintaan menjadi GET sederhana.
Dengan cara ini Anda menjaga desain tetap selaras dengan prinsip REST.
Sunting: Saya tahu solusi ini pada awalnya dimaksudkan untuk memecahkan masalah kata kerja PATCH di beberapa browser dan server tetapi juga berfungsi untuk saya dengan GET kata kerja dalam kasus URL yang sangat panjang yang merupakan masalah yang dijelaskan dalam pertanyaan.
sumber
X-
penghapusan yang ada dan 1.5. itu tidak mengesampingkan spesifikasi yang ada. ...X-
akankah IMO tetap di sini.Jika Anda berkembang di Java dan JAX-RS, saya sarankan Anda menggunakan @QueryParam dengan @GET
Saya memiliki pertanyaan yang sama ketika saya perlu membaca daftar.
Lihat contoh:
Pola URI: “poc / test? Kode = 1 & kode = 2 & kode = 3
@QueryParam akan mengonversi parameter kueri “orderBy = age & orderBy = name” menjadi java.util.List secara otomatis.
sumber