Bir parametre sözdizimsel olarak doğruysa, ancak bir iş kuralını ihlal ederse, bir HTTP 400 (Kötü İstek) durumu döndürmeli miyim?


56

Parametre olarak bir tamsayı alan bir REST bitiş noktasına sahip olduğumu söyleyin:

/makeWaffles?numberOfWaffles=3

Bu durumda, sayının pozitif olmasını istiyorum çünkü negatif sayıda gözleme yapamıyorum (ve 0 gözleme istemek zaman kaybıdır). Bu yüzden pozitif bir tamsayı içermeyen herhangi bir isteği reddetmek istiyorum. Ayrıca bazı maksimum tamsayıları aşan bir isteği reddetmek istiyorum (Şimdilik MAX_INTEGER olduğunu söyleyebiliriz).

Olumsuz sayıda waffle isteyince, HTTP 400 (Kötü İstek) statüsünü iade etmeli miyim? İlk düşüncem evet: bu talebi tamamlamam için geçerli bir sayı değil. Ancak RFC , iş kurallarını atmanın bir nedeni olarak belirtmiyor:

400 (Kötü İstek) durum kodu, sunucunun, bir istemci hatası olarak algılanan bir şey nedeniyle (örneğin hatalı biçimlendirilmiş istek sözdizimi, geçersiz istek mesajı çerçeveleme veya aldatıcı istek yönlendirmesi) nedeniyle isteği işleme koyamayacağını veya işlemeyeceğini belirtir.

Bir iş kuralı bu üç örnekten hiçbirine girmiyor. Sözdizimsel olarak doğru, düzgün bir şekilde çerçevelenmiş ve aldatıcı istek yönlendirme değil.

Öyleyse, bir parametre sözdizimsel olarak doğruysa, ancak bir iş kuralını ihlal ederse, bir HTTP 400 (Kötü İstek) durumu döndürmeli miyim? Yoksa geri dönmek için daha uygun bir durum var mı?



Yanıtlar:


38

Bu harika bir sorudur ve HTTP dönüş kodlarının tarihsel bağlamı (ve görünüşte çelişkili tanımları) göz önüne alındığında yine de oldukça önemlidir. Bu sorunun cevapları arasında bile çelişkili tanımlar var. Bu, kronolojik olarak hareket ederek netleştirilebilir.

RFC 2616 (Haziran 1999)

10.4.1 400 Kötü İstek

İstek hatalı biçimlendirilmiş sözdizimi nedeniyle sunucu tarafından anlaşılamadı. Müşteri, talebi değişiklik yapmadan tekrar etmemelidir.

Bu RFC'den itibaren, bu durum kodu yalnızca sözdizimsel olarak geçersiz isteklere uygulanır. Anlamsal doğrulama için durum kodlarında bir boşluk vardı. Böylece, RFC 4918 ortaya çıktığında, yeni bir kod doğdu.

RFC 4918 (Haziran 2007)

11.2. 422 İşlenemeyen Varlık

422 (İşlenemeyen Varlık) durum kodu, sunucunun istek varlığının içerik türünü anladığını (dolayısıyla bir 415 (Desteklenmeyen Medya Türü) durum kodunun uygun olmadığını) ve istek varlığının sözdiziminin doğru olduğunu (yani 400 (Kötü İstek) ) durum kodu uygun değil) ancak içerdiği talimatları işleme koyamadı. Örneğin, bir XML istek gövdesi iyi biçimlendirilmiş (yani, sözdizimsel olarak doğru), ancak anlamsal olarak hatalı XML talimatları içeriyorsa, bu hata durumu oluşabilir.

422 İşlenemeyen Varlık, 4xx durum kodlarının orijinal spesifikasyonundaki anlamsal doğrulama boşluğunu doldurmak için kuruldu. Bununla birlikte, 2014 yılında, 400'ü artık sözdizimine özgü olmayan genelleyen bir başka RFC ortaya çıkmıştır .

RFC 7231 (Haziran 2014, açıkça RFC 2616'nın modası geçmiş)

6.5.1. 400 Kötü İstek

400 (Kötü İstek) durum kodu, sunucunun, bir istemci hatası olarak algılanan bir şey nedeniyle (örneğin hatalı biçimlendirilmiş istek sözdizimi, geçersiz istek mesajı çerçeveleme veya aldatıcı istek yönlendirmesi) nedeniyle isteği işleme koyamayacağını veya işlemeyeceğini belirtir.

422 tanımının, 400'ün uygunsuz olmasının, 400'ün (RFC 2616'dan itibaren) yalnızca hatalı istek sözdizimi için döndürülmesi gerektiğinden kaynaklandığına dikkat edin. Bununla birlikte, RFC 7231'den itibaren katı sözdizimi hatası tanımı artık 400 için geçerli değildir .

Elimizdeki soruya dönün: 422 teknik olarak daha spesifik olsa da, bu bağlamda, API parametrelerinin anlamsal doğrulaması için 400 ya da 422'nin kullanıldığını görebiliyordum. 422'yi kendi API'lerimde kullanmakta tereddüt ediyorum, çünkü 422'nin tanımı bu noktada teknik olarak modası geçmiş (resmi olarak herhangi bir yerde tanınıp tanınmadığını bilmiyorum). Fran'in 422 kullanımını teşvik eden cevabında yer alan makale, 2012'de, RFC 7231'in HTTP 400'ü netleştirmesinden iki yıl önce yazıldı. Sadece birinin ya da diğerinin standartlaştırıldığından emin olun.


42

İlk cevabı okudum ve kabul etmedim, çünkü en azından benim okumamda kötü bir istek (400), "isteğinizi yerine getiremiyorum çünkü temelde bir şeyler yanlış." Ve ben 422 döndürmek için dava yapan bu yazıyı buldum .

IETF çıkışlı

422 İşlenemeyen Varlık (WebDAV; RFC 4918) İstek iyi oluşturulmuş ancak anlamsal hatalar nedeniyle izlenememiştir.

İsteğiniz iyi şekillendiğinden, ancak doğrulama kurallarınızı geçmediğinden bu daha uygun bir yanıt gibi görünüyor.


5
"400 kötü sözdizimi, 422 kötü anlambilim" anlamına geldiğini açıkladığını duydum.
cbojar

33
Tüm x00 kodları jenerik kodları "hepsini yakala" dır. 400 uygunsuz değil , sadece daha az spesifik .
Jack,

1
İyi cevap, ama @GoFree tarafından verilen cevap benim için daha anlamlı.
Ewerton

2
Herkesin bildiği kodları döndürmek için gerçekten güçlü bir durum var. Kesinlikle herkes 422'ye bakmak zorunda kalacak ve bahse girerim ki çoğu hala ne yapacağını bilemeyecek.
sylvanaar

8

Evet, bitiş noktasının zımni sözleşmesini izlemeyen girdi "müşteri hatası olarak algılanan bir şeydir" ve 400 döndürmelidir.

Bunun istisnası, iş kuralının güvenlikle ilgili olup olmadığıdır (o zaman 401 Unauthorizedya 403 Forbiddenda daha iyi olurdu). Alternatif olarak, eğer bir 400 gönderilirse, bir şeyin varlığına dair bilgi sızdırılır ve ardından bir 404 Not Founddaha uygun olabilir.


8

Hayır yapmamalısın. HTTP kodları, uygulamanızın HTTP katmanı içindir. İş kuralları tamamen farklı bir katmandır ve uygulamaya özeldir, bu nedenle kendi "protokolünüzü" bulmanız gerekir.

Bir kıyametin olduğunu ve HTTP protokolünden Güvercinleri kullanmaya geçmeniz gerektiğini hayal edin. Güvercinlerin herhangi bir geri dönüş kodu yoktur, bu nedenle iş katmanınızı değiştirmek için iş katmanınızı değiştirmeniz gerekir. Ancak işiniz hiçbir şekilde değişmedi, bu yüzden iş katmanını değiştirmeniz gerekmez. Bu iki katman (taşıma ve iş) arasında sıkı bir bağlantı olduğunu gösterir.

Soruya geri dönün: Yapmanız gereken şey, isteğinizde neler olduğunu açıklayan bir kuruluşla birlikte "200 Tamam" dır. Şartname açıkça söylüyor:

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .

200 tamam

İstek başarılı oldu. Yanıtı ile döndürülen bilgi girişi kullanılan yönteme bağlıdır , örneğin,

POST Projenin sonucunu açıklayan veya içeren bir varlık;

HTTP isteğiniz başarılı oldu mu? Evet, web sunucusu bu istekle ne yapılacağını bilir (örneğin, uygulamanızın sunucu bölümüne iletin). Web sunucusu daha sonra POSTed verilerini alan, onları işler (sizin durumunuzda doğrular) ve uygulamanızın istemci kısmına normal bir cevap (HTTP yanıtının gövdesinde) gönderir. . Uygulamanın sunucu kısmındaki bu cevap "Harika, bana gönderdiğiniz veriler geçerli" ya da "Üzgünüm, gönderdiğiniz veriler geçerli değil" olabilir. Ve cevabın ne anlama geldiğini anlamak için müvekkilinizin uygulama kısmına bağlıdır.

Not: "400 Kötü İstek" , web sunucusunun ne istediğinizi anlamadığı anlamına gelir . Bu, sunucunuzun uygulamanızın bir kısmının isteği almadığı anlamına gelir. Ya da en azından :-) demek istediği buydu.

EDIT : Az önce farkettim ki, POST değil GET isteğinde bulundun. Bu kötü bir fikir çünkü GET başvurunun durumunu değiştirmemelidir. GET'in basitçe sunucudan veri alması gerekiyordu. Ancak isteğinizde aslında uygulamanın durumunu değiştiriyorsunuz, bu yüzden gerçekten POST kullanıyor olmalısınız.


1
Evet, bu durumda 404'ü iade etmek iyi. Sunucunun her zaman bir açıklama ile birlikte her zaman 200 Tamam göndermesi gerektiğini söylemiyorum.
GoFree

Daha iyi açıklama şimdiye kadar gördüm. Bunu alabilir aynı soruyu ve tüm kelime benden farklıydı düşünüyor gibi görünüyor ve siz @GoFree
Ewerton

@GoFree Bu API Tasarım yeniden düşünmek için gerçekten iyi bir cevap. Ancak, bir REST API kullandığımız zaman HTTP'yi ve yanıt kodunu iş kuralları katmanının seçkin bir parçası olarak kullanmamız gerekmiyor mu?
Thomas Lauria

1
@Thomas Lauria Henüz RESTFUL API uygulamasının doğru şekilde uygulandığını görmedim. Ancak, REST API bugün bir terimdir, bu yüzden her şirketin arkasındaki konsepti anlamadan onu kullanması gerekir (teknoloji değil). Yani evet, her yerde yanlış bir şekilde kullanılıyor. Programcıların genelde yarattığı şey bir REST API değil, HTTP API veya HTTP AŞIRI API'dir. Aslında birkaç iyi RESTFUL uygulamadan biri HTTP'nin kendisidir :)
GoFree

1
Uygulama vb çok düşük ya da eksik çok yüksek ya da giriş değeri, stokta ürün, herhangi bir iş düzeyindeki hataları tanımlamak için tepki vücutta bir "hata" alanını içeriyorsa Kullanılması 200-OK özellikle mantıklıdır
Roland

-3

Herkesin hemfikir olacağından emin değilim, ancak 409 - Çatışma kullanıyoruz. 409 sayılı devletin çoğu, sistem devletiyle daha fazla bir çelişki teşkil ediyor, ancak kabul edilen aralığın dışında kalan bir veri değeri çatışmasının istek sahibi tarafından tespit edilebileceği ve 409'un kabul edilebilir bir kullanımı olduğunu kabul ettik. doğru şekilde oluşturulmuştur ancak istenildiği gibi işlenemez. Ancak, bir dizi yanıt vermek istemiyorsanız, sadece 400 vermek hala kabul edilebilir.


5
409, "bunu koymaya çalıştığın devlet, başka bir müşterinin bunu koymaya çalıştığı devletle çakışıyor" anlamına geliyor, eşzamanlı yazmaları engellemek için (örneğin ETAG'leri kullanarak)
Jack
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.