REST, HTTP DELETE ve parametreler


135

Bir HTTP DELETE isteğine parametre sağlamada RESTful olmayan herhangi bir şey var mı?


Benim senaryom "Bunu silmek istediğinizden emin misiniz?" senaryo. Bazı durumlarda, kaynağın durumu istenen silme işleminin geçersiz olabileceğini gösterir. Muhtemelen bir silme işleminin onaylanması gereken bazı senaryoları kendiniz hayal edebilirsiniz.

Benimsediğimiz çözüm, silme işlemine devam etmenin uygun olduğunu belirtmek için silme isteğine bir parametre iletmektir ("? Force_delete = true")

Örneğin

DELETE http://server/resource/id?force_delete=true

O zamandan beri hala dinlendirici olduğuna inanıyorum:

(a) DELETE'in anlamı değiştirilmiyor - kullanıcı yine de normal bir DELETE isteği gönderebilir, ancak bu 409 ile başarısız olabilir ve yanıtın gövdesi nedenini açıklayacaktır. Başarısız olabilir diyorum çünkü (açıklamaya değmeyen nedenlerden dolayı) bazı durumlarda kullanıcıyı uyarmak için bir neden yoktur.

(b) Roy'un tezinde bunun REST ruhuna aykırı olduğunu önerecek hiçbir şey yok - HTTP REST'in yalnızca bir uygulaması olduğu için neden HTTP parametrelerini iletmek önemli olsun?


Birisi bana bunun neden RESTful olmadığına dair kesin bir ifadeye işaret edebilir mi?

İlgili bir soruda, kullanıcı force_delete belirtmezse 409 Conflict, o zaman geri dönüyorum - bu en uygun yanıt kodu mu?


Takip et

Biraz daha araştırdıktan sonra, DELETE'e parametre eklemenin birkaç ilkeyi ihlal edebileceğini düşünüyorum.

Birincisi, uygulamanın muhtemelen "Tekdüzen Arayüzü" ihlal ettiğidir ( Roy'un tezinin 5.1.5 bölümüne bakın).

'Force_delete' ekleyerek, zaten iyi tanımlanmış DELETE yöntemine ek bir kısıtlama ekliyoruz. Bu kısıtlama sadece bizim için anlamlıdır.

Onay diyaloğu gerçekten bir kullanıcı arabirimi sorunu olduğundan ve yine tüm istemciler silme işlemini onaylamak istemeyeceğinden, bunun "5.1.2 İstemci-Sunucu" yu ihlal ettiğini de iddia edebilirsiniz.

Önerileriniz var mı?


1
Roy'un tezi için URL'niz 404. ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm işe yarayan bir ")" içeriyor .
NuclearPeon

Yanıtlar:


78

Hayır, RESTful değil. URI'ye bir verb ( force_delete) koymanızın tek nedeni , PUT / DELETE yöntemlerinin kullanılamadığı bir ortamda GET / POST yöntemlerini aşırı yüklemeniz gerekmesidir. DELETE yöntemini kullanımınıza bakılırsa, durum böyle değildir.

HTTP hata kodu 409/Conflict, RESTful hizmetinin işlemi gerçekleştirmesini engelleyen bir çatışmanın olduğu durumlarda kullanılmalıdır, ancak yine de kullanıcının çakışmayı kendi başına çözme ihtimali vardır. API'nin istenen işlemi gerçekleştirmesini engelleyen hiçbir şey olmadığından, silme öncesi onay (silmeyi engelleyecek gerçek çatışmaların olmadığı durumlarda) kendi başına bir çakışma değildir.

Alex'in dediği gibi (onu kimin olumsuz oy verdiğini bilmiyorum, doğru söylüyor), bu kullanıcı arayüzünde ele alınmalıdır, çünkü bu tür bir RESTful hizmeti istekleri işler ve bu nedenle vatansız olmalıdır (yani, bir isteğin sunucu tarafı bilgileri).

Bunun kullanıcı arayüzünde nasıl yapılacağına dair iki örnek şu şekildedir:

  • HTML5 öncesi : * kullanıcıya bir JS onay iletişim kutusu gösterir ve isteği yalnızca kullanıcı onaylarsa gönderir
  • HTML5 : * DELETE işlemine sahip bir form kullanın; burada form yalnızca "Onayla" ve "İptal" düğmelerini içerecektir ("Onayla", gönder düğmesi olacaktır)

(*) Lütfen 5'ten önceki HTML sürümlerinin PUT ve DELETE HTTP yöntemlerini yerel olarak desteklemediğini unutmayın, ancak çoğu modern tarayıcı bu iki yöntemi AJAX çağrıları aracılığıyla yapabilir. Tarayıcılar arası destekle ilgili ayrıntılar için bu ileti dizisine bakın .


Güncelleme (ek araştırma ve tartışmalara dayalı olarak):

Hizmetin force_delete=truebayrağın mevcut olmasını gerektirdiği senaryo , Roy Fielding'in tezinde tanımlanan tek tip arayüzü ihlal ediyor . Ayrıca, HTTP RFC'ye göre, DELETE yöntemi kaynak sunucuda (istemci) geçersiz kılınabilir, bu da bunun hedef sunucuda (hizmet) yapılmadığı anlamına gelir.

Dolayısıyla, hizmet bir DELETE isteği aldığında, herhangi bir ek onaya ihtiyaç duymadan onu işlemelidir (hizmetin işlemi gerçekten gerçekleştirip gerçekleştirmediğine bakılmaksızın).


2
Hangi REST kısıtlamasının ihlal edildiğini açıklayabilir misiniz? URI'lerin istemciye karşı opak olması gerektiğini düşünürsek, neden istemcinin beklentilerinin, bir kaynağı silen ancak diğerini silmeyi başaramayan bir HTTP DELETE kullanımıyla karşılanmadığına inanıyorsunuz? 409'un döndürülecek en iyi durum kodu olduğundan emin değilim, ancak biraz garip bir uygulama olmasının yanı sıra, kırılan herhangi bir REST kısıtlaması bulamıyorum.
Darrel Miller

2
@Darrel: (imho) HTTP standartlarına göre çalışmayan DELETE yöntemiyle tek tip arayüzü ihlal ediyor. Standart bir REST hizmetini kabul eden bir REST istemcisi düşünün - hizmet, istemciye eklenmesi gerektiğini nasıl bildirecek force_delete=true? HTTP RFC'ye göre, DELETE yöntemi kaynak sunucuda (istemci) geçersiz kılınabilir, bu da bunun hedef sunucuda (hizmet) yapılmadığını gösterir. Anladığım kadarıyla, hizmet bir DELETE isteği aldığında, herhangi bir onaya ihtiyaç duymadan işlemesi gerektiğidir (hizmet gerçekten işlemi gerçekleştirip gerçekleştirmediğine bakılmaksızın).
MicE

1
@Chris, ikinci noktanıza: evet, benim de anladığım bu, yani devlet gerçek bir çatışma öneriyor, onaylamaya gerek yok. Sorunuzda yaptığınız güncellemeyi yeni fark ettim ve kabul ediyorum - kendim araştırırken, aynı sonuca vardım (bunun tek tip arayüzü ihlal ettiği ve onayın istemci / kullanıcı arayüzünde yapılması gerektiği) yan). Ayrıca burada çok ilginç bir ileti dizisiyle karşılaştım
MicE

2
@MicE Bu senaryoyu halletmenin ideal bir yolu olmadığı konusunda size büyük ölçüde katılıyorum. Sadece "RESTful değil" etiketi konusunda biraz seçici davranıyorum. Bir süre burada bu cümle her şeye atıldı. Bununla birlikte, bir kaynağı SİLME girişiminde bulunursanız ve bir hata alırsanız (403 yasaklı 409'dan daha iyi olurdu) diyen bir medya türü için kurallar tanımlamak mümkün olacaktır, o zaman müşteri ilgili bir kaynakta DELETE'i denemelidir. "force_delete = true" üzerine tacking yaparak. Bir bakıma biraz yetkilendirmeye benziyor. GET yapın, 401 alın, kimlik doğrulama başlığı ekleyin ve tekrar GET yapın.
Darrel Miller

2
@Darrel: bu çok iyi bir nokta, teşekkürler. Ve insanların RESTful değil etiketini kendim attığını gördüm. Günümüzde hizmetler ve web uygulamaları arasındaki engel çok sisli hale geliyor olabilir, bu nedenle bir grup insan bunu saf hizmet açısından görebilirken, diğerleri bunu karma bir uygulama / hizmet açısından görebilir. Doğrulamanın nasıl yapılacağına dair asıl sorunun devreye girdiği yer burasıdır. @Chris: güncellendi - çok ilginç bir konu ve tartışma için teşekkür ederim efendim!
MicE

35

Bunun huzur verici olmadığını düşünüyorum. Dinlendirici hizmetin, kullanıcıyı bir silme işlemini onaylamaya zorlama gerekliliğini yerine getirmesi gerektiğini düşünmüyorum. Bunu kullanıcı arayüzünde halledecektim.

Force_delete = true belirtmek, bu bir programın API'sı olsaydı mantıklı olur mu? Birisi bu kaynağı silmek için bir komut dosyası yazıyorsa, kaynağı gerçekten silmeleri için onu force_delete = true belirtmeye zorlamak ister miydiniz?


Cevabınızın ilk paragrafı sizin fikrinizdir ve buna saygı duyuyorum ancak literatürde URI'nin bu şekilde kullanılmasını yasaklayan bir şeye işaret etmediniz - hala kaynağı tanımlıyor ve en uygun HTTP fiili kullanılıyor. Sorularınıza cevap olarak; evet yine de mantıklı olacaktır (bence). Bir komut dosyasının (belki de CURL'ye dayalı) 409 yanıtına saygı göstermesini ve kullanıcıya isteğin nasıl yeniden gönderilebileceğini önermesini beklerdim - tümü yanıt bedenime göre
Chris McCauley

Web API'sini bir programın API'siyle karşılaştırmanın iyi bir noktası. Bu genellikle bir API'nin RESTful olup olmadığını öğrenmenin iyi bir yoludur.
laurent

18

Bu eski bir soru, ama işte bazı yorumlar ...

  1. SQL'de DELETE komutu, bağımlı nesnelerin de silinmesi gerektiğini belirtmenize izin veren "CASCADE" parametresini kabul eder. Bu, mantıklı olan bir DELETE parametresi örneğidir, ancak 'man rm' başkalarını sağlayabilir. Bu durumlar bir parametre olmadan REST / HTTP'de nasıl uygulanabilir?
  2. @Jan, URL'nin yol kısmının bir kaynağı tanımladığı, ancak sorgu dizesinin tanımadığı (en azından zorunlu olarak değil) iyi yapılandırılmış bir kural gibi görünüyor. Örnekler çoktur: aynı kaynağı farklı bir biçimde almak, bir kaynağın belirli alanlarını almak, vb. Sorgu dizesini kaynak tanımlayıcının bir parçası olarak düşünürsek, "aynı kaynağın farklı görünümleri" kavramına sahip olmak imkansızdır. HTTP içerik anlaşması gibi RESTful olmayan mekanizmalara dönmeden (birçok nedenden dolayı istenmeyen olabilir).

Yıllar sürdüğü için pek bir konuşma olmasa da bunu sohbete eklediğiniz için teşekkürler.
silviot

6

Alex'in cevabına ek olarak:

Not olduğunu http: // sunucu / kaynak / id FORCE_DELETE = true daha tanımlayan farklı bir kaynak http: // sunucu / kaynak / id . Örneğin, / müşteriler /? Durum = eski veya / müşteriler / silmeniz çok büyük bir farktır.

Ocak


Katılmıyorum, aynı kaynağı tanımlamak için birden fazla URI sağlamakta özgürüm.
Chris McCauley

19
Evet - herkes ortalığı karıştırmakta özgür :-)
Jan Algermissen

: Kanonik URI'lerinin Endikasyon bu konuda yardım olabilir googlewebmastercentral.blogspot.com/2009/02/...
Fareler

@Chris Bir kaynağın temsilini döndüren yalnızca bir URI olmalıdır. Diğer URI'ler aynı kavrama başvurabilir, ancak bir GET yapmak 303 Bkz. Diğerini döndürmelidir. Ve buna yönelik bariz itirazı karşılamak için, /foo.xml ve /foo.json iki farklı kaynaktır.
Darrel Miller

@Darrell - katılıyorum ama format burada bir sorun değil. Ayrıca .format, Rails'te ve diğer çerçevelerde bir kuraldır, REST'in bir parçası değildir - bunu tam olarak uygulamak için HTTP'deki içerik pazarlığını MIME veya mikro biçimlerle kullanmanız gerekir.
Chris McCauley
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.