Saat mengeluarkan permintaan HTTP DELETE, URI permintaan harus sepenuhnya mengidentifikasi sumber daya yang akan dihapus. Namun, apakah dapat menambahkan meta-data tambahan sebagai bagian dari badan entitas permintaan?
Saat mengeluarkan permintaan HTTP DELETE, URI permintaan harus sepenuhnya mengidentifikasi sumber daya yang akan dihapus. Namun, apakah dapat menambahkan meta-data tambahan sebagai bagian dari badan entitas permintaan?
Jawaban:
Spek tidak secara eksplisit melarang atau mengecilkannya, jadi saya cenderung mengatakan itu diizinkan.
Microsoft melihatnya dengan cara yang sama (saya dapat mendengar gumaman di antara hadirin), mereka menyatakan dalam artikel MSDN tentang Metode DELETE dari ADO.NET Framework Layanan Data :
Jika permintaan DELETE termasuk badan entitas, tubuh diabaikan [...]
Selain itu, inilah yang dikatakan RFC2616 (HTTP 1.1) sehubungan dengan permintaan:
Content-Length
atau Transfer-Encoding
(bagian 4.3)Untuk tanggapan, ini telah didefinisikan:
Pembaruan terbaru untuk spesifikasi HTTP 1.1 ( RFC 7231 ) secara eksplisit memungkinkan badan entitas dalam permintaan DELETE:
Muatan dalam pesan permintaan DELETE tidak memiliki semantik yang ditentukan; mengirimkan badan muatan pada permintaan DELETE dapat menyebabkan beberapa implementasi yang ada menolak permintaan tersebut.
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
Jadi ia datang dengan peringatan kompatibilitas mundur, menyarankan bahwa standar berikutnya akan mengatakan: 'ya! DELETE
dapat memiliki tubuh`.
A payload within a DELETE request message has no defined semantics
. Jadi tubuh diizinkan.
Beberapa versi Tomcat dan Jetty tampaknya mengabaikan badan entitas jika ada. Yang bisa menjadi gangguan jika Anda bermaksud menerimanya.
Salah satu alasan untuk menggunakan tubuh dalam permintaan penghapusan adalah untuk kontrol konkurensi optimis.
Anda membaca versi 1 dari catatan.
GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }
Rekan Anda membaca versi 1 dari catatan.
GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }
Kolega Anda mengubah catatan dan memperbarui database, yang memperbarui versi ke 2:
PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }
Anda mencoba menghapus catatan:
DELETE /some-resource/1 { id:1, version:1 }
409 Conflict
Anda harus mendapatkan pengecualian kunci optimis. Baca kembali catatan, lihat bahwa ini penting, dan mungkin tidak menghapusnya.
Alasan lain untuk menggunakannya adalah untuk menghapus beberapa catatan sekaligus (misalnya, kotak dengan kotak centang pemilihan baris).
DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content
Perhatikan bahwa setiap pesan memiliki versinya sendiri. Mungkin Anda dapat menentukan beberapa versi menggunakan beberapa tajuk, tetapi menurut George, ini lebih sederhana dan jauh lebih nyaman.
Ini berfungsi di Tomcat (7.0.52) dan Spring MVC (4.05), mungkin juga versi sebelumnya:
@RestController
public class TestController {
@RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
SomeBean echoDelete(@RequestBody SomeBean someBean) {
return someBean;
}
}
If-Unmodified-Since
atau Etag
untuk itulah itu tujuan).
Tampak bagi saya bahwa RFC 2616 tidak menentukan ini.
Dari bagian 4.3:
Kehadiran badan pesan dalam permintaan ditandai dengan dimasukkannya bidang Konten-Panjang atau Transfer-Pengkodean dalam header pesan permintaan. Badan pesan TIDAK HARUS dimasukkan dalam permintaan jika spesifikasi metode permintaan (bagian 5.1.1) tidak memungkinkan pengiriman badan hukum dalam permintaan. Server HARUS membaca dan meneruskan badan pesan atas permintaan apa pun; jika metode permintaan tidak termasuk semantik yang ditentukan untuk badan-badan, maka badan pesan HARUS diabaikan ketika menangani permintaan.
Dan bagian 9.7:
Metode DELETE meminta server asal menghapus sumber yang diidentifikasi oleh Request-URI. Metode ini DAPAT ditimpa oleh intervensi manusia (atau cara lain) pada server asal. Klien tidak dapat dijamin bahwa operasi telah dilakukan, bahkan jika kode status yang dikembalikan dari server asal menunjukkan bahwa tindakan telah berhasil diselesaikan. Namun, server TIDAK HARUS menunjukkan keberhasilan kecuali, pada saat respon diberikan, itu bermaksud untuk menghapus sumber daya atau memindahkannya ke lokasi yang tidak dapat diakses.
Respons yang berhasil HARUS menjadi 200 (OK) jika respons mencakup entitas yang menggambarkan status, 202 (Diterima) jika tindakan belum diberlakukan, atau 204 (Tidak Ada Konten) jika tindakan telah diberlakukan tetapi respons tidak termasuk sebuah entitas.
Jika permintaan melewati cache dan Request-URI mengidentifikasi satu atau lebih entitas yang di-cache saat ini, entri-entri tersebut HARUS diperlakukan sebagai basi. Respons terhadap metode ini tidak dapat di-cache.c
Jadi itu tidak diizinkan atau dianulir secara eksplisit, dan ada kemungkinan proxy sepanjang jalan dapat menghapus isi pesan (meskipun HARUS membaca dan meneruskannya).
Hanya kepala, jika Anda menyediakan tubuh dalam permintaan DELETE Anda dan menggunakan load balancer Google cloud HTTPS, itu akan menolak permintaan Anda dengan kesalahan 400. Saya membenturkan kepala ke dinding dan mengetahui bahwa Google, untuk alasan apa pun, menganggap permintaan DELETE dengan tubuh adalah permintaan yang cacat.
for whatever reason
- karena spek mengatakan demikian: P
DELETE
adalah yang terakhir.
Tampaknya ElasticSearch menggunakan ini: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api
Yang berarti Netty mendukung ini.
Seperti disebutkan dalam komentar itu mungkin tidak lagi terjadi
Roy Fielding pada milis HTTP mengklarifikasi bahwa pada milis http https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0123.html dan mengatakan:
Badan GET / DELETE benar-benar dilarang memiliki dampak apa pun terhadap pemrosesan atau interpretasi permintaan
Ini berarti bahwa tubuh tidak boleh memodifikasi perilaku server. Lalu dia menambahkan:
selain dari keharusan untuk membaca dan membuang byte yang diterima untuk menjaga pembingkaian pesan.
Dan akhirnya alasan untuk tidak melarang tubuh:
Satu-satunya alasan kami tidak melarang pengiriman tubuh adalah karena itu akan menyebabkan implementasi yang malas dengan asumsi tidak ada tubuh yang akan dikirim.
Jadi, sementara klien dapat mengirim badan muatan, server harus menjatuhkannya dan API tidak boleh menetapkan semantik untuk badan muatan pada permintaan tersebut.
Ini tidak didefinisikan .
Muatan dalam pesan permintaan DELETE tidak memiliki semantik yang ditentukan; mengirimkan badan muatan pada permintaan DELETE dapat menyebabkan beberapa implementasi yang ada menolak permintaan tersebut.
https://tools.ietf.org/html/rfc7231#page-29
Menggunakan DELETE with a Body berisiko ... Saya lebih suka pendekatan ini untuk Operasi Daftar daripada REST:
Operasi Reguler
DAPATKAN / objek / Mendapat semua Objek
DAPATKAN / objek / ID Mendapat Objek dengan ID yang ditentukan
POST / objek Menambahkan Objek baru
PUT / objek / ID Menambahkan Objek dengan ID yang ditentukan, Memperbarui Objek
HAPUS / objek / ID Menghapus objek dengan ID yang ditentukan
Semua tindakan Kustom adalah POST
POST / objek / addList Menambahkan Daftar atau Array Objek yang termasuk dalam tubuh
POST / objek / deleteList Menghapus Daftar Objek yang termasuk dalam tubuh
POST / objek / customQuery Membuat Daftar berdasarkan permintaan kustom di tubuh
Jika klien tidak mendukung operasi Anda yang diperluas, mereka dapat bekerja secara teratur.
POST
bukanlah cara RESTy yang baik untuk menciptakan sumber daya baru karena semantik respons POST tidak jelas, terutama dalam konteks header Lokasi. Anda pada dasarnya meninggalkan HTTP dan menumpuk RPC di atasnya. "HTTP / REST way" yang tepat adalah membuat sumber daya menggunakan PUT
w / If-None-Match: *
header (atau menentukan metode HTTP yang tepat, lihat MKCOL
dll).
Saya tidak berpikir jawaban yang bagus untuk ini telah diposting, meskipun ada banyak komentar bagus pada jawaban yang ada. Saya akan mengangkat inti dari komentar-komentar itu menjadi jawaban baru:
Paragraf ini dari RFC7231 telah dikutip beberapa kali, yang memang meringkasnya.
Muatan dalam pesan permintaan DELETE tidak memiliki semantik yang ditentukan; mengirimkan badan muatan pada permintaan DELETE dapat menyebabkan beberapa implementasi yang ada menolak permintaan tersebut.
Apa yang saya lewatkan dari jawaban lain adalah implikasinya. Ya itu diizinkan untuk memasukkan badan pada DELETE
permintaan, tetapi secara semantik tidak berarti. Apa ini sebenarnya berarti bahwa mengeluarkan DELETE
permintaan dengan badan permintaan secara semantik setara dengan tidak termasuk badan permintaan.
Termasuk badan permintaan tidak akan berpengaruh pada permintaan, jadi tidak pernah ada gunanya memasukkannya.
tl; dr: Secara teknis DELETE
permintaan dengan badan permintaan diizinkan, tetapi tidak pernah berguna untuk melakukannya.
Jika ada yang mengalami pengujian masalah ini, Tidak, itu tidak didukung secara universal.
Saat ini saya sedang menguji dengan Sahi Pro dan sangat jelas panggilan http DELETE menghapus data tubuh yang disediakan (daftar besar id untuk dihapus secara massal sesuai desain titik akhir).
Saya telah melakukan kontak dengan mereka beberapa kali dan juga mengirim dalam tiga paket skrip, gambar, log untuk mereka tinjau dan mereka masih belum mengonfirmasi hal ini. Tambalan yang gagal, dan panggilan konferensi yang tidak terjawab oleh dukungan mereka kemudian dan saya masih belum mendapatkan jawaban yang solid.
Saya yakin Sahi tidak mendukung ini, dan saya akan membayangkan banyak alat lain mengikuti suite.
Mungkin url GitHUb di bawah ini akan membantu Anda, untuk mendapatkan jawabannya. Sebenarnya, Application Server seperti Tomcat, Weblogic menolak panggilan HTTP.DELETE dengan permintaan payload. Jadi dengan mengingat semua hal ini, saya telah menambahkan contoh di github, tolong perhatikan