Bir HTTP DELETE isteği yayınlanırken, istek URI'sı silinecek kaynağı tamamen tanımlamalıdır. Ancak, isteğin varlık gövdesinin bir parçası olarak fazladan meta veri eklenmesine izin veriliyor mu?
Bir HTTP DELETE isteği yayınlanırken, istek URI'sı silinecek kaynağı tamamen tanımlamalıdır. Ancak, isteğin varlık gövdesinin bir parçası olarak fazladan meta veri eklenmesine izin veriliyor mu?
Yanıtlar:
Spesifikasyon açıkça yasaklamaz veya cesaretini kırmaz, bu yüzden izin verildiğini söyleme eğilimindeyim.
Microsoft aynı şekilde görüyor (izleyicide mırıltı duyabiliyorum), onlar ADO.NET Veri Hizmetleri Çerçevesi DELETE Yöntemi hakkında MSDN makalesinde :
DELETE isteği bir varlık gövdesi içeriyorsa, gövde yok sayılır [...]
Ek olarak, RFC2616'nın (HTTP 1.1) isteklerle ilgili söyledikleri:
Content-Length
veya Transfer-Encoding
üstbilginin eklenmesiyle bildirilir (bölüm 4.3)Yanıtlar için bu tanımlanmıştır:
HTTP 1.1 spesifikasyonunda ( RFC 7231 ) yapılan en son güncelleme , bir DELETE isteğinde bir varlık gövdesine açıkça izin verir:
DELETE istek iletisindeki bir yükün tanımlanmış bir anlamı yoktur; bir DELETE isteği üzerine bir yük gövdesi göndermek, mevcut bazı uygulamaların isteği reddetmesine neden olabilir.
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.
Geriye dönük bir uyumluluk uyarısı ile birlikte gelir, bir sonraki standardın 'evet! DELETE
bir vücuda sahip olabilir.
A payload within a DELETE request message has no defined semantics
. Böylece vücuda izin verilir.
Tomcat ve Jetty'nin bazı sürümleri, bir varlık gövdesini varsa yok sayar. Bunu almayı amaçladıysanız bu bir sıkıntı olabilir.
Gövdeyi silme isteğinde kullanmanın bir nedeni iyimser eşzamanlılık kontrolüdür.
Bir kaydın 1. sürümünü okudunuz.
GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }
İş arkadaşınız kaydın 1. sürümünü okur.
GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }
İş arkadaşınız kaydı değiştirir ve sürümü 2 olarak güncelleyen veritabanını günceller:
PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }
Kaydı silmeye çalışıyorsunuz:
DELETE /some-resource/1 { id:1, version:1 }
409 Conflict
İyimser bir kilit istisnası olmalı. Kaydı tekrar okuyun, önemli olduğunu görün ve silinmeyebilir.
Bunu kullanmanın bir başka nedeni, aynı anda birden fazla kaydı silmektir (örneğin, satır seçimi onay kutularına sahip bir ızgara).
DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content
Her iletinin kendi sürümü olduğuna dikkat edin. Belki birden çok başlık kullanarak birden çok sürüm belirtebilirsiniz, ancak George tarafından bu daha basit ve çok daha uygundur.
Bu, Tomcat (7.0.52) ve Spring MVC (4.05) 'de çalışır, muhtemelen daha önceki sürümlerde de bulunur:
@RestController
public class TestController {
@RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
SomeBean echoDelete(@RequestBody SomeBean someBean) {
return someBean;
}
}
If-Unmodified-Since
veya Etag
Ne için olduklarını olduğuna göre).
Bana öyle geliyor ki RFC 2616 bunu belirtmiyor.
Bölüm 4.3'ten:
Bir istekte bir ileti gövdesinin varlığı, isteğin ileti başlıklarına bir İçerik Uzunluğu veya Aktarım Kodlaması üstbilgisi alanının eklenmesiyle bildirilir. İstek yönteminin (bölüm 5.1.1) belirtimi, isteklerde varlık gövdesi gönderilmesine izin vermiyorsa, ileti gövdesi bir istekte BULUNMAMALIDIR. Bir sunucu, herhangi bir istek üzerine bir ileti gövdesini okumalı ve iletmelidir; istek yöntemi varlık gövdesi için tanımlı anlambilim içermiyorsa, istek işlenirken ileti gövdesi göz ardı EDİLMELİDİR.
Ve bölüm 9.7:
DELETE yöntemi, kaynak sunucunun Request-URI tarafından tanımlanan kaynağı silmesini ister. Bu yöntem, kaynak sunucuya insan müdahalesi (veya başka yollarla) geçersiz kılınabilir. Kaynak sunucudan döndürülen durum kodu, eylemin başarıyla tamamlandığını gösterse bile, istemcinin işlemin gerçekleştirildiği garanti edilemez. Ancak, yanıt verildiği sırada kaynağı silmeyi veya erişilemeyen bir konuma taşıma niyetinde olmadığı sürece sunucu başarıyı GÖSTERMEMELİDİR.
Yanıt, durumu tanımlayan bir varlık içeriyorsa başarılı bir yanıt 200 (Tamam), eylem henüz yürürlüğe girmediyse 202 (Kabul edildi) veya işlem yürürlüğe girdiyse ancak yanıt içermiyorsa 204 (İçerik Yok) olmalıdır bir varlık.
İstek bir önbellekten geçerse ve İstek URI'sı şu anda önbelleğe alınmış bir veya daha fazla varlığı tanımlarsa, bu girdilere eski olarak davranılmalıdır. Bu yönteme verilen yanıtlar önbelleğe alınamaz. C
Bu nedenle, açıkça izin verilmez veya izin verilmez ve yol boyunca bir proxy'nin ileti gövdesini kaldırma olasılığı vardır (her ne kadar onu okuyup iletmelidir).
Sadece bir adım yukarı, DELETE isteğinizde bir gövde sağlar ve bir google bulut HTTPS yük dengeleyici kullanıyorsanız, isteğinizi 400 hatayla reddeder. Kafamı bir duvara çarpıyordum ve Google'ın, hangi nedenle olursa olsun, bir bedenle SİL talebinin hatalı biçimlendirilmiş bir talep olduğunu düşündüğünü öğrendim.
for whatever reason
- çünkü spec böyle diyor: P
DELETE
İkincisi bir ileti gövdesi kullanmaktır .
Görünen o ki, Elastik Arama bunu kullanıyor: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api
Yani Netty bunu destekliyor.
Yorumlarda belirtildiği gibi, artık durum böyle olmayabilir
HTTP posta listesindeki Roy Fielding, http posta listesinde https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0123.html adresini açıklıyor ve şöyle diyor:
GET / DELETE kuruluşunun, talebin işlenmesi veya yorumlanması üzerinde herhangi bir etkisi olması kesinlikle yasaktır.
Bu, gövdenin sunucunun davranışını değiştirmemesi gerektiği anlamına gelir. Sonra ekler:
mesaj çerçevesini korumak için alınan baytları okuma ve atma zorunluluğunun yanı sıra.
Ve son olarak bedeni yasaklamamanın nedeni:
Bir ceset göndermeyi yasaklamamamızın tek nedeni, bunun hiçbir ceset gönderilmeyeceğini varsayarak tembel uygulamalara yol açmasıdır.
İstemciler yük gövdesini gönderebilirken, sunucular bunu bırakmalı ve API'ler bu isteklerde yük gövdesi için bir anlam tanımlamamalıdır.
Bu tanımlanmamış .
DELETE istek iletisindeki bir yükün tanımlanmış bir anlamı yoktur; bir DELETE isteği üzerine bir yük gövdesi göndermek, mevcut bazı uygulamaların isteği reddetmesine neden olabilir.
https://tools.ietf.org/html/rfc7231#page-29
Bir Kuruluşla DELETE kullanmak risklidir ... REST üzerinden Liste İşlemleri için bu yaklaşımı tercih ederim:
Düzenli Operasyonlar
GET / nesneler / Tüm Nesneleri Alır
GET / object / ID Belirtilen kimliğe sahip bir Nesne alır
POST / nesneler Yeni bir Nesne ekler
PUT / object / ID Belirtilen kimliğe sahip bir nesne ekler, bir nesneyi günceller
DELETE / object / ID Belirtilen kimliğe sahip nesneyi siler
Tüm Özel işlemler POST
POST / objects / addList Gövdeye dahil edilen Nesneler Listesi veya Dizisi ekler
POST / objects / deleteList Gövdede bulunan Nesneler Listesini siler
POST / objects / customQuery Gövdedeki özel sorguyu temel alan bir Liste oluşturur
Bir müşteri genişletilmiş işlemlerinizi desteklemiyorsa, düzenli olarak çalışabilir.
POST
yeni kaynaklar oluşturmak için iyi bir RESTy yolu değildir çünkü POST yanıtlarının semantiği özellikle Konum başlıkları bağlamında belirsizdir. Aslında HTTP'yi geride bırakıyorsunuz ve RPC'yi üst üste topluyorsunuz. Uygun "HTTP / REST yolu", başlığı PUT
w / kullanarak If-None-Match: *
(veya uygun HTTP yöntemlerini belirterek, MKCOL
vb.) Kullanarak kaynak oluşturmaktır .
Mevcut cevaplar hakkında çok sayıda harika yorum olmasına rağmen, bunun için iyi bir cevap gönderildiğini düşünmüyorum. Bu yorumların özünü yeni bir cevaba kaldıracağım:
RFC7231'den bu paragraf birkaç kez alıntılanmıştır, bu da özetlemektedir.
DELETE istek iletisindeki bir yükün tanımlanmış bir anlamı yoktur; bir DELETE isteği üzerine bir yük gövdesi göndermek, mevcut bazı uygulamaların isteği reddetmesine neden olabilir.
Diğer cevaplardan kaçırdığım şey ima idi. Evet, DELETE
isteklere bir gövde eklemesine izin verilir , ancak anlamsal olarak anlamsızdır. Bunun gerçekten anlamı, DELETE
bir istek gövdesi ile bir istek yayınlamanın anlamsal olarak bir istek gövdesi içermemesine eşdeğer olmasıdır.
Bir istek gövdesinin dahil edilmesinin, istek üzerinde herhangi bir etkisi olmamalıdır, bu nedenle hiçbir zaman dahil edilmesinin bir anlamı yoktur.
tl; dr: Teknik DELETE
olarak bir istek gövdesine sahip bir talebe izin verilir, ancak bunu yapmak asla yararlı olmaz.
Herhangi birinin bu sorun testine girmesi durumunda, Hayır evrensel olarak desteklenmez.
Şu anda Sahi Pro ile test ediyorum ve çok açık bir http DELETE çağrı sağlanan herhangi bir vücut veri şeritler (id noktaların uç nokta tasarımına göre toplu olarak silmek için büyük bir liste) şeritler.
Onlarla birkaç kez iletişim kurdum ve incelemeleri için üç ayrı komut dosyası, resim, günlük paketi gönderdim ve hala bunu onaylamadılar. Başarısız bir yama ve cevapsız bir konferans daha sonra desteklerini arayarak hala sağlam bir cevap alamadım.
Sahi'nin bunu desteklemediğinden eminim ve diğer birçok aracın paketi takip ettiğini düşünürdüm.
Aşağıdaki cevap olabilir GitHUb url size yardımcı olacaktır. Aslında, Tomcat, Weblogic gibi Uygulama Sunucusu HTTP.DELETE çağrısını istek yükü ile reddediyor. Tüm bunları akılda tutarak, github'a örnek ekledim, lütfen şuna bir göz atın