Meskipun spesifikasi HTTP 1.1 tampaknya mengizinkan badan pesan pada permintaan DELETE , tampaknya menunjukkan bahwa server harus mengabaikannya karena tidak ada semantik yang ditentukan untuk itu.
4.3 Isi Pesan
Server HARUS membaca dan meneruskan badan pesan berdasarkan permintaan apa pun; jika metode permintaan tidak menyertakan semantik yang ditentukan untuk badan entitas, maka badan pesan HARUS diabaikan saat menangani permintaan.
Saya telah meninjau beberapa diskusi terkait tentang topik ini di SO dan seterusnya, seperti:
- Apakah badan entitas diperbolehkan untuk permintaan HTTP DELETE?
- Muatan Metode Permintaan HTTP
- HTTP GET dengan isi permintaan
Sebagian besar diskusi tampaknya setuju bahwa memberikan badan pesan pada HAPUS mungkin diperbolehkan , tetapi umumnya tidak disarankan.
Lebih lanjut, saya telah memperhatikan tren di berbagai pustaka klien HTTP di mana semakin banyak peningkatan tampaknya dicatat untuk pustaka ini untuk mendukung badan permintaan di DELETE. Sebagian besar perpustakaan tampaknya menurut, meskipun kadang-kadang dengan sedikit penolakan awal.
Kasus penggunaan saya meminta penambahan beberapa metadata yang diperlukan pada DELETE (misalnya "alasan" untuk penghapusan, bersama dengan beberapa metadata lain yang diperlukan untuk penghapusan). Saya telah mempertimbangkan opsi berikut, tidak ada yang tampak sepenuhnya sesuai dan sejalan dengan spesifikasi HTTP dan / atau praktik terbaik REST:
- Isi Pesan - Spesifikasi menunjukkan bahwa badan pesan di DELETE tidak memiliki nilai semantik; tidak sepenuhnya didukung oleh klien HTTP; bukan praktik standar
- Header HTTP Kustom - Mewajibkan header khusus umumnya bertentangan dengan praktik standar ; menggunakannya tidak konsisten dengan API saya lainnya, tidak ada yang memerlukan tajuk khusus; selanjutnya, tidak ada respons HTTP yang baik yang tersedia untuk menunjukkan nilai header khusus yang buruk (mungkin pertanyaan yang sama sekali berbeda)
- Header HTTP Standar - Tidak ada header standar yang sesuai
- Parameter Kueri - Menambahkan parameter kueri sebenarnya mengubah URI Permintaan yang sedang dihapus; bertentangan dengan praktik standar
- Metode POST - (mis.
POST /resourceToDelete { deletemetadata }
) POST bukanlah opsi semantik untuk dihapus; POST sebenarnya mewakili tindakan berlawanan yang diinginkan (yaitu POST membuat bawahan sumber daya; tetapi saya perlu menghapus sumber daya) - Beberapa Metode - Memisahkan permintaan DELETE menjadi dua operasi (misalnya PUT menghapus metadata, lalu DELETE) membagi operasi atom menjadi dua, berpotensi meninggalkan status yang tidak konsisten. Alasan penghapusan (dan metadata terkait lainnya) bukan bagian dari representasi resource itu sendiri.
Preferensi pertama saya mungkin menggunakan badan pesan, kedua setelah header HTTP kustom; namun, seperti yang ditunjukkan, ada beberapa kelemahan dari pendekatan ini.
Apakah ada rekomendasi atau praktik terbaik yang sejalan dengan standar REST / HTTP untuk menyertakan metadata yang diperlukan tersebut pada permintaan DELETE? Apakah ada alternatif lain yang belum saya pertimbangkan?
sumber
Jersey
tidak mengizinkan isi untukdelete
permintaan.Jawaban:
Terlepas dari beberapa rekomendasi untuk tidak menggunakan badan pesan untuk permintaan DELETE, pendekatan ini mungkin sesuai dalam kasus penggunaan tertentu. Ini adalah pendekatan yang akhirnya kami gunakan setelah mengevaluasi opsi lain yang disebutkan dalam pertanyaan / jawaban, dan setelah berkolaborasi dengan konsumen layanan.
Meskipun penggunaan badan pesan tidak ideal, tidak ada opsi lain yang juga cocok. Badan permintaan DELETE memungkinkan kami dengan mudah dan jelas menambahkan semantik di sekitar data / metadata tambahan yang diperlukan untuk menyertai operasi DELETE.
Saya masih terbuka untuk pemikiran dan diskusi lain, tetapi ingin menutup lingkaran tentang pertanyaan ini. Saya menghargai pemikiran dan diskusi semua orang tentang topik ini!
sumber
Apa yang tampaknya Anda inginkan adalah salah satu dari dua hal, tidak ada yang murni
DELETE
:PUT
satu alasan penghapusan diikuti olehDELETE
sumber daya. Setelah dihapus, konten sumber daya tidak dapat lagi diakses oleh siapa pun. 'Alasan' tidak boleh berisi hyperlink ke sumber daya yang dihapus. Atau,state=active
menjadistate=deleted
dengan menggunakanDELETE
metode ini. Sumber daya dengan status = dihapus diabaikan oleh API utama Anda tetapi mungkin masih dapat dibaca oleh admin atau seseorang dengan akses database. Ini diizinkan -DELETE
tidak harus menghapus data pendukung untuk sumber daya, hanya untuk menghapus sumber daya yang diekspos di URI tersebut.Operasi apa pun yang memerlukan badan pesan pada
DELETE
permintaan dapat dipecah menjadi paling umum,POST
untuk melakukan semua tugas yang diperlukan dengan badan pesan, dan aDELETE
. Saya tidak melihat alasan untuk merusak semantik HTTP.sumber
PUT
alasan berhasil danDELETE
sumber daya gagal? Bagaimana keadaan yang tidak konsisten dapat dicegah?Mengingat situasi yang Anda alami, saya akan mengambil salah satu pendekatan berikut:
resource/:id
. Anda dapat membuatnya dapat ditemukan dengan tajuk Tautan pada sumber daya untuk setiap alasan (denganrel
tag pada setiap alasan untuk mengidentifikasi alasan).resource/:id/canceled
. Ini benar-benar mengubah Request-URI dan jelas bukan RESTful. Sekali lagi, tajuk tautan dapat membuatnya dapat ditemukan.Ingatlah bahwa REST bukanlah hukum atau dogma. Anggap saja lebih sebagai panduan. Jadi, jika masuk akal untuk tidak mengikuti panduan untuk domain masalah Anda, jangan. Pastikan saja konsumen API Anda diberi tahu tentang variansnya.
sumber
/orders/:id
akan mengembalikan resource yang sama seperti/orders/:id?exclude=orderdetails
. String kueri hanya memberikan petunjuk ke server - dalam hal ini untuk mengecualikan detail pesanan dalam respons (jika didukung). Demikian pula, jika Anda mengirim DELETE ke/orders/:id
atau/orders/:id?reason=canceled
atau/orders/:id?reason=bad_credit
, Anda masih bertindak pada sumber daya dasar yang sama. Untuk menjaga 'antarmuka seragam', saya akan memiliki alasan default sehingga mengirim parameter kueri tidak diperlukan./foo?123
berarti Anda menghapus sumber daya yang berbeda dari jika Anda mengirim DELETE ke/foo?456
.Saya sarankan Anda memasukkan metadata yang diperlukan sebagai bagian dari hierarki URI itu sendiri. Contoh (Naif):
Jika Anda perlu menghapus entri berdasarkan rentang tanggal, alih-alih meneruskan tanggal mulai dan tanggal akhir dalam isi atau sebagai parameter kueri, susun URI sedemikian rupa sehingga Anda meneruskan informasi yang diperlukan sebagai bagian dari URI.
misalnya
DELETE /entries/range/01012012/31122012
- Hapus semua entri antara 1 Januari 2012 hingga 31 Desember 2012Semoga ini membantu.
sumber
range
ditentukan dalam parameter kueri atau muatan yang merupakan inti dari pertanyaan ini: untuk memahami pendekatan praktik terbaik untuk masalah yang akan saya katakan bukan ini.