Http DELETE kullanarak bir kaynağı silme


124

Öyleyse, Http'deki DELETE fiilinin idempotent olduğu göz önüne alındığında, aşağıdaki isteği yaptığımda, ikinci (veya üçüncü veya dördüncü, vb.) Ne olmalıdır?

DELETE /person/123

İlk kez, kaynak siliniyor ve 204 döndürüyorum (başarılı, içerik yok). Sonraki aramalarda 204'ü mü yoksa 404'ü (bulunamadı) mı iade etmeliyim?

Yanıtlar:


153

Durum bilgisi olmayan bir sistemdeki HTTP istekleri bağımsız olması gerektiğinden, bir isteğin sonuçları önceki bir isteğe bağlı olmamalıdır. İki kullanıcı aynı kaynakta aynı anda SİLME yaptıysa ne olacağını düşünün. İkinci isteğin 404 alması mantıklıdır. Bir kullanıcı iki istekte bulunursa aynı durum geçerli olmalıdır.

DELETE'in iki farklı yanıtı döndürdüğünü tahmin ediyorum, size idempotent gelmiyor. İdempotent isteklerin, sistemi aynı durumda bıraktığını, ille de aynı yanıtı vermediğini düşünmeyi faydalı buluyorum. Bu nedenle, var olan bir kaynağı SİLİN veya var olmayan bir kaynağı SİLMEYİN, sunucu kaynak durumu aynıdır.


4
Teşekkür ederim. Bu çok mantıklı. Gerçekten idempotent'in aynı yanıtı vereceğini düşünüyordum.
Craig Wilson

4
@Craig Dikkatli! Yemek Kitabında, Subbu az önce söylediklerimle tamamen çelişiyor. İdempotansın aynı yanıtı vermesi gerektiği anlamına geldiğini söylüyor. Neyse ki, Subbu RESTFest'te olacak, bu yüzden orada onunla açıklayacağım.
Darrel Miller

58
Var olmayan bir şeyi SİLDİĞİNİZDE, sadece 204 döndürmelisiniz (kaynak hiç var olmasa bile). Müşteri kaynağın gitmesini istedi ve gitti. Bir 404 döndürmek, istemci için önemsiz olan ve gereksiz bir hata durumuna yol açacak olan dahili işlemeyi açığa çıkarır.
Brian

9
@DarrelMiller Sanırım buradaki anahtar kavram, bir kaynağın var olup olmadığını kontrol etmek için DELETE'i kullanmamanız, bunun için önce GET'i kullanmalısınız. Ardından, yanıt 200 ise, bir SİLME gerçekleştirirsiniz; aksi halde bunu yapmaya zahmet etme bile. Bu yüzden DELETE'de her zaman 204 döndürmenin mantıklı olduğunu düşünüyorum.
manei_cc

10
@Brian RFC, böyle davranması gerektiğini söylüyor rm. rmyoksa bir hata döndürür. tools.ietf.org/html/rfc7231#section-4.3.5
Dax Fohl

32

RESTful web hizmetleri yemek kitabı bunun için harika bir kaynaktır. Şans eseri, google önizlemesi DELETE ile ilgili sayfayı gösterir (sayfa 11):

DELETE yöntemi idempotenttir. Bu, sunucunun kaynağı önceki bir istekte silmiş olsa bile, sunucunun yanıt kodu 200 (OK) döndürmesi gerektiği anlamına gelir. Ancak pratikte, DELETE'i idempotent bir işlem olarak uygulamak, sunucunun silinen tüm kaynakları takip etmesini gerektirir. Aksi takdirde, 404 (Bulunamadı) döndürebilir.


Evet, bu harika bir kaynak gibi görünüyor. Ancak, DELETE bölümü benim için açılmıyor (bu sayfa 23 ve önizlemede redaksiyon var). Bu kitabı okudun mu? Sorumun cevabını biliyor musunuz?
Craig Wilson

Bu kitap, REST oluşturmak için sahip olunması gereken bir kitaptır (özellikle bir dilde değil, konuşur).
yves amsellem

7
@Craig Yemek Kitabını Okumak, zaten silmiş olsanız bile 200 OK döndürmeniz GEREKİR diyor. Ancak, uygulamada sunucunun silinen tüm kaynakları izlemesini gerektirecek, bu nedenle 404'ü KULLANABİLİRSİNİZ. Güvenlik endişelerinin her zaman 404'ü geri göndermenizi gerektirebileceğini söylemeye devam ediyor. Sayfa 11.
Darrel Miller

+1 İkincisi ve RESTful hizmetlerini tasarlamak için kitabı şiddetle tavsiye ediyorum.
Paul DelRe

18
Kitap yanlış. Idempotency, durum kodunun aynı olacağı anlamına gelmez. İlgili olan, sunucunun son durumudur.
Julian Reschke

13

Şu anki seçili cevabın söylediği şeye katılıyorum , 2. (ve 3., 4., ...) DELETE bir 404 almalıdır . Ve cevabın 143 olumlu oyu olduğunu fark ettim ama aynı zamanda 54 artı oyu olan zıt bir yorumu da var, bu nedenle topluluk kabaca 3: 1 oranında 2 kampa bölünmüş durumda. İşte bu uzun süreli tartışmayı çözmek için daha fazla bilgi geliyor.

  1. Her şeyden önce, "Ben" ne düşündüğüyle, ne "sen" in düşündüğüyle veya başka bir kitap yazarının ne düşündüğüyle başlamayalım. HTTP özellikleriyle, yani RFC 7231 ile başlayalım.

    • RFC 7231, bölüm 4.3.5 DELETE yalnızca başarılı bir yanıtın 2xx olması gerektiğini belirtti, ancak sonraki bir DELETE'in ne alacağını belirtmedi. Öyleyse daha derine inelim.
    • RFC 7231, bölüm 6.5.4 404 Bulunamadı , 404 yanıtının bir kaynak için olmadığını söylüyor. Belirli bir http yöntemi (özellikle, DELETE değil) başka şekilde ele alınmak üzere çağrılmadığından, sezgisel olarak bir izlenim (ve haklı olarak) elde edebiliriz, bu DELETE /some/resource/which/does/not/exististeğimin bir 404 ile sonuçlanması gerekir. O zaman, DELETE /some/resource/which/happened/to/be/removed/by/someone/else/five/days/agobir 404 de döndürebiliriz. Öyleyse neden DELETE /some/resource/i/deleted/five/seconds/agofarklı olsun? "Ama idempotency ?!" diye bağırdığını duyabiliyorum. Bekle, bu konuya girmek üzereyiz.
    • Tarihsel olarak, 1999'da yayınlanan RFC 2616, en çok başvurulan HTTP 1.1 özellikleriydi. Ne yazık ki idempotency hakkındaki açıklaması belirsizdi , bu da tüm bu tartışmalara yer bırakıyor. Ancak bu özelliklerin yerini RFC 7231 almıştır. RFC 7231, bölüm 4.2.2 Idempotent Methods , vurgu benim:

      Bu yöntemle birden çok özdeş isteğin SUNUCU ÜZERİNDEKİ amaçlanan ETKİSİ, bu tür tek bir isteğin etkisiyle aynıysa, bir istek yöntemi "idempotent" olarak kabul edilir. Bu belirtimle tanımlanan istek yöntemlerinden PUT, DELETE ve güvenli istek yöntemleri idempotenttir .

      Yani, teknik özelliklerde yazılmıştır, idempotency, sunucu üzerindeki etkiyle ilgilidir. Bir 204 döndüren ilk SİLME ve ardından 404 döndüren sonraki SİLME, bu tür farklı durum kodu SİLİNİ idempotent yapmaz. Sonraki bir dönüşü gerekçelendirmek için bu argümanı kullanmak, basitçe alakasızdır.

  2. Tamam, yani idempotency ile ilgili değil. Ama sonra bir takip sorusu olabilir, ya hala sonraki SİLME işleminde 204'ü kullanmayı seçersek? Tamam mı?

    İyi soru. Motivasyon anlaşılabilir bir durumdur: müşterinin hatayı ele alma konusunda endişelenmeden, amaçlanan sonuca ulaşmasına izin vermek. Sonraki DELETE'de 204 döndürmenin büyük ölçüde zararsız bir sunucu tarafı "beyaz yalan" olduğunu söyleyebilirim, ki bu istemci tarafı hemen bir fark göstermeyecektir. Bu yüzden vahşi ortamda bunu yapan ~% 25 insan var ve görünüşe göre hala çalışıyor. Unutmayın ki, böyle bir yalanın anlamsal olarak tuhaf kabul edilebileceğini unutmayın, çünkü GET /non-exist404 döndürür ama DELETE /non-exist204 verir, bu noktada müşteri hizmetinizin bölüm 6.5.4'e tam olarak uymadığını anlayacaktır 404 Bulunamadı .

    Ancak şunu belirtmek isterim ki, RFC 7231 tarafından ima edilen amaçlanan yol, yani 404'ü sonraki DELETE'de döndürmek, ilk etapta bir sorun olmamalıdır. 3 kat daha fazla geliştirici bunu yapmayı seçti ve hiç bir müşterinin 404'ü işleyememesinin neden olduğu büyük bir olay veya şikayet duydunuz mu? Muhtemelen hayır ve bunun nedeni, HTTP DELETE'i (veya bu konuda herhangi bir HTTP yöntemini) uygulayan herhangi bir düzgün istemcinin sonucun her zaman başarılı olacağını körü körüne varsaymamasıdır. 2xx. Ve sonra, geliştirici hata işlemeyi düşünmeye başladığında, akla gelen ilk hatalardan biri 404 Bulunamadı olacaktır. Bu noktada, muhtemelen bir HTTP DELETE işleminin bir 404 hatasını görmezden gelmesinin anlamsal olarak güvenli olduğu sonucuna varacaktır. Ve öyle yaptılar.

Sorun çözüldü.


2
+1 "idempotency, sunucu üzerindeki etkiyle ilgilidir". Titizlikle cevapladı. Aferin! Sonraki DELETE istekleri için 404'e inanıyorum.
nwayve

11

İlk SİLME : 200 veya 204.

Sonraki DELETE'ler : 200 veya 204.

Gerekçe : DELETE idempotent olmalıdır. İkinci bir DELETE'de 404 döndürürseniz, yanıtınız bir başarı kodundan bir hata koduna dönüşür . İstemci programı, DELETE işleminin başarısız olduğu varsayımına bağlı olarak hatalı eylemler gerçekleştirebilir.

Örnek :

  • SİLME işleminizin, istemci programı tarafından yürütülen çok adımlı bir işlemin (veya bir "destanın") parçası olduğunu varsayalım.
  • Müşteri programı, örneğin bir banka işlemi gerçekleştiren bir mobil uygulama olabilir.
  • Diyelim ki istemci programı bir DELETE işlemi için otomatik olarak yeniden deneme yapıyor (bu mantıklı, çünkü DELETE'in idempotent olması gerekiyor).
  • Diyelim ki ilk DELETE başarıyla yürütüldü, ancak 200 yanıtı istemci programına giderken kayboldu.
  • İstemci programı SİLMEYİ yeniden deneyecek.
  • İkinci deneme 404 döndürürse, istemci programı bu hata kodu nedeniyle genel işlemi iptal edebilir.
  • Ancak ilk DELETE sunucuda başarıyla yürütüldüğünden , sistem tutarsız bir durumda bırakılabilir .
  • İkinci deneme 200 veya 204 döndürürse, istemci programı beklendiği gibi devam edecektir.

Sadece bu yaklaşımın kullanımını göstermek için PayPal için HTTP API stil kılavuzu aşağıdaki yönergeye sahiptir:

SİL: Bu yöntem 204 durum kodunu döndürmelidir, çünkü istek bir kaynağı silmek olduğundan ve başarıyla silindiğinden, çoğu durumda herhangi bir içerik döndürmeye gerek yoktur.

DELETE metodunun idempotent olması ZORUNLUDUR, kaynak zaten silinmiş olsa bile yine de 204 döndürmelidir * ÖNERİ *. Genellikle API tüketicisi, kaynağın bu işlemin bir parçası olarak mı yoksa daha önce mi silindiğini umursamaz. 404 yerine 204 döndürülmesinin nedeni de budur.


1
Soru şu, müşteriye önemli olduğunu, ne olduğunu o kaynak silinmiş veya kaynak silinmiş olduğunu. Ya başka bir müşteri destan sırasında kaynağı sildiyse? Müşterinin hedefine ulaşıldığını göz önünde bulundurarak gerçekten başarısız olmak istiyor musunuz?
Darrel Miller

1
@DarrelMiller İyi nokta. Daha önemli olan iş bağlamına bağlıdır. Ancak genel olarak, kaynak başka bir istemci tarafından silinmiş olsa bile, ikinci bir DELETE girişiminde 204 döndürmeyi tercih ederim. Müşterinin hedefine ulaşıldığı için hizmetin başarısız olmasını (yani 404) istemiyorum.
Paulo Merson

2
Başkalarının da bahsettiği gibi, idempotency yanıt kodunuz değil, sunucu durumunuzdur.
Niranjan

@Niranjan idempotency'nin sunucu durumu hakkında olduğunu kabul ediyorum, ancak farklı bir yanıt kodu, istemcinin devam eden bir destanı iptal ederek gereksiz yere sunucu durumunu değiştirmesine neden olabilir.
Paulo Merson

@Paulo Merson Müşteri HİÇBİR ZAMAN var olmayan bir öğenin silinmesini isterse hangi kodu iade edeceksiniz? 204? veya 404? Her zaman 204 döndürürseniz, dönüş kodunu kontrol etmenin anlamı nedir?
frenchone
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.