REST DELETE gerçekten idempotent mi?


166

DELETE'ın idempotent olması gerekiyor.

Http://example.com/account/123 SİLİRSİM hesap silinecektir.

Tekrar yaparsam hesap artık mevcut olmadığından 404 bekler miyim? Daha önce var olmayan bir hesabı SİLMEYE çalışırsam ne olur?


11
Cevaplara ek olarak, genel olarak idempotent karakteristiğe çok fazla odaklanmamanızı öneririm: değişme ve eşzamanlı istekler hakkında hiçbir şey söylemez. Örneğin, aynı "R1" PUT isteğinin N + 1'i aynı etkiye sahip olmalı, ancak başka bir istemcinin kendi aralarınızda farklı bir PUT / DELETE "R2" isteği yapıp yapmadığını bilmiyorsunuz, bu nedenle n R1 = R1 ve m R2 = R2, araya eklenmiş "R1" ve "R2" isteklerini aldığınız bir şey, yalnızca tek bir istemcinin perspektifini alırsanız mutlaka idempotent görünmeyecektir.
Bruno

Yanıtlar:


189

Idempotence, istek tamamlandıktan sonra sistemin durumunu ifade eder


Her durumda (hata sorunlarının dışında - aşağıya bakın), hesap artık mevcut değildir.

Gönderen burada

"Yöntemler" idempotence "özelliğine de sahip olabilir ( hata veya son kullanma sorunlarının yanı sıra ) N> 0 özdeş isteklerin yan etkileri tek bir istekle aynıdır. GET, HEAD, PUT ve DELETE paylaşım yöntemleri Ayrıca, OPTIONS ve TRACE yöntemlerinin yan etkileri OLMAMALIDIR ve bu nedenle doğal olarak idempotenttir. "


Anahtar biti , N> 0 özdeş isteklerin yan etkileri olan tek bir istekle aynıdır.

Durum kodunun farklı olmasını beklemek doğru olur, ancak bu temel idempotency kavramını etkilemez - sunucunun durumunda ek değişiklikler yapmadan isteği bir kereden fazla gönderebilirsiniz.


3
Yan etkiler! == sunucu durumu
wprl

2
@wprl Bu "yan etkinin" gerçekte ne olduğu hakkında bir tartışma var. "Sunucu durumu" veya istemciye yanıt olabilir. leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza

İşte ikinci bir DELETE üzerindeki 404'ün sunucunun durumunu gerçekten değiştirebileceğine dair bir argüman: stackoverflow.com/a/45194747/317522
Paulo Merson

1
@PauloMerson Teşekkürler, şahsen ikinci dönüşün 404 veya 200 olup olmadığı önemli değil, sunucunun durumu değişmedi, bu yüzden bundan memnunum.
Chris McCauley

46

Idempotent , aldığınız yanıt kodu hakkında değil, isteğin etkisi ile ilgilidir.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 diyor:

Metodlar ayrıca "idempotence" özelliğine de sahip olabilirler (bu, hata veya son kullanma sorunlarının yanı sıra) N> 0 özdeş isteklerin yan etkilerinin tek bir istekle aynı olmasıdır.

Farklı bir yanıt kodu alabilirsiniz, ancak aynı kaynağa N + 1 DELETE istekleri göndermenin etkisi aynı kabul edilebilir.


13

Önemli ayrım, idempotent'in tüm etkileri veya yanıtları değil, yan etkileri ifade etmesidir. Bunu yaparsanız , etki 123 hesabının artık sunucudan silinmesidir. Bu tek ve tek etki, tek ve tek sunucunun durumuna değişir . Şimdi aynı isteği tekrar yaptığınızı varsayalım, sunucu farklı yanıt verecek, ancak durumu aynı.DELETE http://example.com/account/123DELETE http://example.com/account/123

Başka bir hesabı kaldırmak veya bir hata günlüğü bırakmak gibi hesap eksik olduğu için DELETE isteği sunucu durumunu farklı bir şekilde değiştirmeye karar vermedi. Hayır, aynı DELETE isteğini milyon kez çağırabilirsiniz ve sunucunun ilk aradığınız durumla aynı olduğundan emin olabilirsiniz .


7

Gönderen HTTP RFC :

Metodlar ayrıca "idempotence" özelliğine de sahip olabilirler (bu, hata veya son kullanma sorunlarının yanı sıra) N> 0 özdeş isteklerin yan etkilerinin tek bir istekle aynı olmasıdır.

Bunun "yan etkiler" olduğunu, "yanıt" olmadığını unutmayın.


7

Evet. Yanıt kodundan bağımsız olarak.

Gönderen HTTP 1.1 için en son RFC (vurgu benim):

İstemci sunucunun yanıtını okuyabilmeden önce bir iletişim hatası oluşursa istek otomatik olarak yinelenebildiğinden, idempotent yöntemler ayırt edilir. Örneğin, bir istemci bir PUT isteği gönderirse ve herhangi bir yanıt alınmadan temel bağlantı kapatılırsa, istemci yeni bir bağlantı kurabilir ve idempotent isteği yeniden deneyebilir. Orijinal istek başarılı olsa bile, isteğin yinelenmesinin aynı amaçlanan etkiye sahip olacağını bilir, ancak yanıt farklı olabilir.

Yanıtın farklı olabileceğini açıkça söylüyor. Daha da önemlisi, kavramın nedenine dikkat çekiyor: bir eylem idempotent ise, müşteri herhangi bir hatayla karşılaştığında eylemi tekrarlayabilir ve bunu yaparak hiçbir şeyi çökmeyeceğini bilir; değilse, istemcinin GETeylemi güvenli bir şekilde tekrar etmeden önce bir öncekinin etkili olup olmadığını görmek için ek bir sorgu (muhtemelen ) yapması gerekecektir. Sunucu böyle bir garanti verebildiği sürece, eylem idempotenttir. Başka bir yorumdan alıntı :

Hesaplama idempotence bir sistemin sağlamlığı ile ilgilidir. İşler başarısız olabileceğinden (örn. Ağ kesintisi), bir hata algılandığında nasıl iyileşirsiniz? En kolay kurtarma sadece tekrar yapmaktır, ancak bu sadece tekrar yapmak idempotent ise işe yarar. Örneğin discard(x), idempotent, ama pop()değil. Her şey hata kurtarma ile ilgilidir.


3

Başka bir cevabımdan alıntı :

Tarihsel olarak, 1999'da yayınlanan RFC 2616, en çok başvurulan HTTP 1.1 spesifikasyonlarıydı. Ne yazık ki , idempotency hakkındaki açıklaması belirsizdi , bu da tüm bu tartışmalara yer bırakıyor. Ancak bu spesifikasyonların yerini RFC 7231 aldı. RFC 7231, bölüm 4.2.2 Idempotent Metotlar , alıntı benim:

Bu yöntemle birden fazla özdeş talebin amaçlanan SUNUCU ÜZERİNDEKİ ETKİSİ, bu tür tek bir talebin etkisi ile aynı ise, bir talep yöntemi "idempotent" olarak kabul edilir. Bu spesifikasyon ile tanımlanan talep yöntemlerinden PUT, DELETE ve güvenli talep yöntemleri idempotenttir .

Yani, özelliklerde yazılmıştır, idempotency tamamen sunucu üzerindeki etkisi ile ilgilidir. 204 döndüren ilk DELETE ve ardından 404 döndüren DELETE, bu tür farklı durum kodu DELETE'i idempotent yapmaz. Bir sonraki 204 dönüşünü haklı çıkarmak için bu argümanı kullanmak basitçe önemsizdir.


Tamam, bu idempotency ile ilgili değil. Ama sonra bir takip sorusu olabilir, eğer sonraki DELETE'de hala 204 kullanmayı seçersek? Tamam mı?

İyi soru. Motivasyon anlaşılabilir: müşterinin hataların ele alınmasından endişe etmeden yine de amaçlanan sonucuna ulaşmasını sağlamak. Sonraki DELETE 204 döndürme, istemci tarafı hemen bir fark anlatmayacak büyük ölçüde zararsız sunucu tarafı "beyaz yalan" olduğunu söyleyebilirim. Bu yüzden vahşi doğada bunu yapan insanlar var ve hala çalışıyor. Sadece böyle bir yalanın anlamsal olarak garip kabul edilebileceğini unutmayın, çünkü "GET / non-there" 404 döndürür ancak "DELETE / non-exist" 204 verir, bu noktada müşteri hizmetinizin tam olarak uymadığını anlar bölüm 6.5.4 404 Bulunamadı .

Ancak daha sonra, RFC 7231 tarafından ima edilen, yani sonraki DELETE üzerine 404 döndürülen amaçlanan yol, ilk etapta bir sorun olmamalıdır. Daha birçok geliştirici bunu yapmayı seçti. Muhtemelen, HTTP DELETE (veya bu konuda herhangi bir HTTP yöntemi) uygulayan herhangi bir istemcinin, sonucun her zaman başarılı olacağını körü körüne varsaymayacağı için 2xx. Ve sonra, geliştirici hata işlemeyi düşünmeye başladığında, 404 Bulunamadı ilk akla gelen hatalardan biri olacaktır. Bu noktada, umarım bir HTTP DELETE işleminin 404 hatasını yoksaymasının anlamsal olarak güvenli olduğu sonucuna varabilir. Sorun çözüldü.


2

Bence aynı şey, 404 - Hesap yok.

400 - Kötü İstek'i tartışabilirsiniz. Ancak REST anlamında, üzerinde işlem yapmak istediğiniz nesne mevcut değildir. Bu 404 anlamına gelir.


1
400 üretmek için nesnenin eskiden var olduğunu bilmelisiniz ki bu çok huzur vericidir.
annakata

1
@annakata, 400 eskiden var olan kaynaklar için bile değil (belki aklınızda 410 / aklınız var), kötü istekler için "İstek, hatalı biçimlendirilmiş sözdizimi nedeniyle sunucu tarafından anlaşılamadı."
Bruno

3
@Bruno - Ne anlama geldiğinin farkındayım, OP bunu gösterdi.
annakata

1
Bence 200 iyi olur. Sunucunun durumunun hesabın gitmiş olmasını istiyorsunuz. Hangi talebin gerçekten ortadan kalktığının önemi var mı? Hala ikinci istek üzerine gitti, sunucu durumu değişmedi.
Andy
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.