Geçerli bir istek yerine boş bir veri için uygun REST yanıt kodu nedir?


332

Örneğin, için bir GET isteği çalıştırıyorsunuz users/9ancak # 9 numaralı bir kullanıcı yok. En iyi yanıt kodu hangisidir?

  • 200 TAMAM
  • 202 Kabul edildi
  • 204 İçerik Yok
  • 400 Hatalı İstek
  • 404 Bulunamadı

19
İpucu: Kullanıcı 9'u buldunuz mu?
Chris Pfohl

42
İpucu 2: Kullanıcı 9 bulunamadı mı?
Tomasz Nurkiewicz

18
@IMB kim 204 diyor? "İçerik Yok", aradığınız varlığın var olduğunu, ancak temsili olmadığını belirtir. Örneğin, 15 numaralı kimliğe sahip blogda yorum yoksa ve 15 numaralı blogun yorumları için boş bir liste döndürmek istemediyseniz: "/ blog / 15 / comments" NoContent döndürür. Diğer yandan, eğer blog 15 mevcutsa, '404 Bulunamadı' daha uygundur.
Chris Pfohl

12
@Crisfole demek istemediniz ". Öte yandan blog 15 mevcut değilse , '404 Bulunamadı' daha uygundur"
gdoron Monica

15
Kesinlikle @gdoron yaptım! :) Teşekkürler. Ne yazık ki bunu düzenlemek ve düzeltmek için yaklaşık üç yıl geç kaldım.
Chris Pfohl

Yanıtlar:


249

TL; DR: Kullanım 404

Bkz. Bu Blog . Çok iyi açıklıyor.

Blogun yorumlarının özeti 204:

  1. 204 No Content bir tarayıcı için yanıt kodu olarak çok kullanışlı değildir (HTTP özelliklerine göre tarayıcıların bunu 'görünümü değiştirmeyin' yanıt kodu olarak anlamaları gerekir).
  2. 204 No Content olduğunu , ancak bir şey dönmek zorunda kalmadan başarı göstermek isteyebilirsiniz ajax web hizmetleri için çok yararlı. (Özellikle geri bildirim gerektirmeyen DELETEveya benzeri durumlarda POST).

Bu nedenle, sorunuzun cevabı 404sizin durumunuzda kullanmaktır . 204, yanıt olarak bir tarayıcıya sık sık geri dönmemeniz gereken özel bir yanıt kodudur GET.

Hatta daha az uygun olan diğer müdahale kodları 204ve 404:

  1. 200başarılı bir şekilde getirdiğiniz her şeyin bedeni ile birlikte iade edilmelidir. Getirdiğiniz varlık mevcut olmadığında uygun değildir.
  2. 202sunucu bir nesne üzerinde çalışmaya başladığında, ancak nesne henüz tam olarak hazır olmadığında kullanılır. Kesinlikle burada durum böyle değil. Bir GETisteğe yanıt olarak 9 numaralı kullanıcının inşaatına başlamadınız veya başlamayacaksınız . Bu her türlü kuralı ihlal eder.
  3. 400, kötü biçimlendirilmiş bir HTTP isteğine yanıt olarak kullanılır (örneğin, hatalı biçimlendirilmiş http üstbilgileri, yanlış sıralanmış segmentler, vb.). Bu neredeyse kesinlikle hangi çerçeveyi kullanırsanız kullanın. Kendi sunucunuzu sıfırdan yazmadığınız sürece bununla başa çıkmak zorunda kalmamalısınız. Düzenleme : Daha yeni RFC'ler artık anlamsal olarak geçersiz istekler için 400'ün kullanılmasına izin vermektedir.

Wikipedia'nın HTTP durum kodları açıklaması özellikle yararlıdır. Tanımları www.w3.org adresindeki HTTP / 1.1 RFC2616 belgesinde de görebilirsiniz.


8
Not: 200'lerde yanıt kodları başarıyı gösterir. 400'lerde yanıt kodları arızayı gösterir. Birinci ve ikinci noktalar, 204yanıt kodu ile ilgilidir (İçerik Yok).
Chris Pfohl

227
-1 olarak 404'e geri dönecek kayıt bulunmayan başarılı bir çağrıya yanıt olarak şiddetle karşı çıkıyorum . Web dışı bir uygulama için bir API ile uğraşan bir geliştirici olarak, aradığım API uç noktasının neden bulunmadığını izlemek için API geliştiricileriyle iletişim kurma saatlerini boşa harcadım. raporlanacak veriler. 204'ün bir tarayıcı için özellikle yararlı olmadığı göz önüne alındığında, akıllı cihaz evrenimizdeki API uç noktalarının çoğu kullanımının tarayıcı tabanlı olmadığı ve muhtemelen AJAX kullananlar olduğu için köpeği sallayan kuyruk gibi bir şey. Yine de puan almak için üzgünüm.
Matt Cashatt

38
@MatthewPatrickCashatt istediğiniz gibi oy kullanmakta özgürsünüz. Nihayet insanların neden beni küçümsediğini anlıyorum , ama mantık hala yanlış. Bir 404 almak, rotanın anlamsız olduğu anlamına gelmez, bu yerde kaynak olmadığı anlamına gelir. Tam durak. Bu, talep ediyorsanız /badurlveya /user/9böyle bir kullanıcı yoksa doğrudur . Bir geliştirici, 'Bulunamadı' ifadesinden daha iyi bir neden ifadesi ekleyerek yardımcı olabilir, ancak zorunlu değildir.
Chris Pfohl

19
@Crisfole Özellikle 404 W3 tanımına dayanarak katılmıyorum (aşağı oy değil, okumaya devam et) The server has not found anything matching the Request-URI. Web / uygulama sunucusu aslında İstek-URI'sı ile eşleşen bir EYLEM buldu, ancak db sunucusu bulamadı. Ancak, aynı zamanda diyor ki This status code is commonly used when [...] no other response is applicable, bu yüzden kullanımını biraz doğrular düşünüyorum (ben kabul / sevmiyorum bile).
Daevin

8
Bahsettiğim noktaya değindiğinizi sanmıyorum: 404 tehlikeli bir şekilde kafa karıştırıcı. Arayan kişiye bir neden ifadesini veya yanıtın gövdesini kontrol etmek, durum koduna güvenmediğiniz anlamına gelir; bu durumda yararlı değildir.
Adrian Baker

364

Boş verilerle 204 veya 200 lehine 404'e şiddetle karşıyım. Ya da en azından biri 404 ile bir yanıt kuruluşu kullanmalıdır.

İstek alındı ​​ve düzgün işlendi - sunucudaki uygulama kodunu tetikledi, bu yüzden gerçekten bir istemci hatası olduğunu ve bu nedenle tüm istemci hata kodları (4xx) sınıfının uymadığını söyleyemiyor.

Daha da önemlisi, 404 birçok teknik nedenden dolayı olabilir. Örneğin, uygulamanın geçici olarak devre dışı bırakılması veya sunucudan kaldırılması, proxy bağlantısı sorunları vb. Bu nedenle, istemci "boş sonuç kümesi" anlamına gelen 404 ile "hizmet bulunamıyor, daha sonra tekrar deneyin" anlamına gelen 404'ü ayırt edemez.

Bu ölümcül olabilir: Şirketinizde yıllık ikramiye nedeniyle çalışanların tümünü listeleyen bir muhasebe hizmeti düşünün. Ne yazık ki, çağrıldığında bir kez 404 döndürür. Bu, kimsenin bir bonus için ödenmediği veya uygulamanın şu anda yeni bir dağıtım için kapalı olduğu anlamına mı geliyor?

-> Verilerinin kalitesini önemseyen uygulamalar için, yanıt veren varlık içermeyen 404 bu nedenle hemen hemen hiç kolay değildir.

Ayrıca, birçok müşteri çerçevesi 404'e başka soru sorulmadan bir istisna atarak yanıt verir. Bu, istemci geliştiriciyi bu özel durumu yakalamaya, değerlendirmeye ve ardından örneğin bir izleme bileşeni tarafından alınan bir hata olarak günlüğe kaydetmeye ya da yoksaymaya karar vermeye karar verir. Bu benim için de hoş görünmüyor.

204 üzerinden 404'ün avantajı, istenen kaynağın neden bulunamadığına dair bazı bilgiler içerebilecek bir yanıt varlığını geri gönderebilmesidir. Ancak bu gerçekten alakalı ise, 200 OK yanıtı kullanmayı düşünebilir ve sistemi yük verisinde hata yanıtlarına izin verecek şekilde tasarlayabilir. Alternatif olarak, yapılandırılmış bilgiyi arayan kişiye geri göndermek için 404 yanıtının faydalı yükü kullanılabilir. Ayrıştırabileceği XML veya JSON yerine bir html sayfası alırsa, bu, arayanın bakış açısından geçerli olabilecek "sonuç yok" yanıtı yerine teknik bir şeyin yanlış gittiğinin iyi bir göstergesidir. Veya bunun için bir HTTP yanıt üstbilgisi kullanılabilir.

Yine de boş bir tepki ile 204 veya 200 tercih ederim. Bu şekilde, isteğin teknik yürütme durumu, isteğin mantıksal sonucundan ayrılır. 2xx "teknik uygulama tamam, bu sonuç, onunla başa" anlamına gelir.

Çoğu durumda boş bir sonucun kabul edilebilir olup olmadığına karar vermesi müşteriye bırakılmalıdır. Müşteri, doğru bir teknik uygulamaya rağmen yanıt veren varlık olmadan 404'ü iade ederek, vakaların sadece hata olmayan hatalar olarak değerlendirilmesine karar verebilir.

Başka bir hızlı benzetme: "Sonuç bulunamadı" için 404 döndürmek, bir SQL sorgusu sonuç döndürmediyse DatabaseConnectionException özel durumunu atmak gibidir. İşi halledebilir, ancak aynı istisnayı atan ve daha sonra geçerli bir sonuçla karıştırılacak birçok olası teknik neden vardır.


30
'Bulunamadı' ifadesinin teknik nedenleri sunucu hataları olarak da bilinir. Bunlar 500'lerde olmalı. Özellikle: "Hizmet bulunamadı" dır 503 Service Unavailable.
Chris Pfohl

43
Asker ayrıca belirli bir kaynağı soruyordu: tek bir kullanıcı ( /usersrota değil /users/9, yani "Kullanıcı # 9 olarak bilinir"), bu nedenle 'boş sonuç kümesi' karşılaştırmanız mantıklı değil. 404, nesnenin mevcut olmadığı anlamına gelir.
Chris Pfohl

29
404 sadece istenen kaynağın (bu durumda 9 numaralı kullanıcı) bulunamadığını gösterir. Uygulama kodunun tetiklenip tetiklenmediği ile ilgisi yoktur, bir arka uç uygulamasının yanıt verip vermemesiyle ilgisi yoktur. Web sunucusu sorunun ne olduğuyla ilgiliydi, soruda ters proxy'den bahsedilmiyordu.
Chris Pfohl

29
Bu cevaptaki mantık korkutucu derecede yanlıştır.
Kurt Spindler

21
404: istemci belirli bir sunucuyla iletişim kurabildi, ancak sunucu ne istediğini bulamadı. Kelimenin tam anlamıyla: istek alındı, iyi ve düzgün biçimlendirildi (kötü istek 400), kimliği doğrulandı veya kamuya açıklandı (yetkisiz 401 / yasak 403), ödeme gerekli değil (ödeme gerekli 402), istek yöntemi iyiydi (yöntem 405'e izin verilmiyor) ), istek kabul tatmin olabilir (kabul edilemez 406). Kullanıcı kaynağı aldığında 200 Ok kullanılmalıdır. Boş bir kaynak değildir. 400 aralığı istemci hataları içindir 500 aralığı sunucu hataları içindir Kısaca: Gerekçeniz kapalı.
Derk-Jan

62

İlk başta 204'ün mantıklı olacağını düşündüm, ancak tartışmalardan sonra 404'ün tek doğru doğru yanıt olduğuna inanıyorum. Aşağıdaki verileri göz önünde bulundurun:

Kullanıcılar: John, Peter

METHOD  URL                      STATUS  RESPONSE
GET     /users                   200     [John, Peter]
GET     /users/john              200     John
GET     /users/kyle              404     Not found
GET     /users?name=kyle`        200     []
DELETE  /users/john              204     No Content

Bazı bilgiler:

  1. arama bir dizi döndürür, yalnızca eşleşmesi yoktu, ancak içeriği var: boş bir dizi .

  2. 404 elbette en çok istenen sunucu tarafından desteklenmeyen URL'ler için bilinir, ancak eksik bir kaynak aslında aynıdır. Eşleştirilmesine
    rağmen /users/:name, users/kyleKyle kullanıcısı kullanılabilir bir kaynak değildir, bu nedenle 404 hala geçerlidir. Bu bir arama sorgusu değildir, dinamik bir URL'nin doğrudan referansıdır , yani 404'tür.

Her neyse, iki sentim :)


9
REST API için ağırlığımı bu stilin arkasına atmak. Kaynağın / kullanıcılara veya / kullanıcılara çağrı yoluyla kaynağın var olacağı söylenmedikçe hiçbir müşteri / users / kyle istememelidir. Name = kyle
Gary Barker

@GaryBarker Ancak bu bir şekilde "kullanıcı girişi" olduğundan, API hala doğru şekilde işlemek zorundadır. 404 SİZİN istemcinizde önlemek gerekir, ancak aslında ilk etapta kontrol edileceği garanti edilemez. API'nın tasarlanması, özellikle kontrol edilen kullanıcı girişi açısından müşterinizin tam uygulaması düşünülmeden yapılmalıdır.
RicoBrassers

En çok katıldığım cevap bu. API'lerin çalışmasını nasıl istediğimin mükemmel bir örneği. @ GaryBarker'ın yorumu da mükemmel. Bir şeyi kimliğe göre aradığınızda bir hata var ve yok. Çağrı yapmadan önce kimliğin var olduğunu bilmelisiniz. Çoğunlukla bazı 'başarılı' boş yanıtlar almak sadece hatayı daha da aşağıya indirdiğinden, user.name veya bir şey yaparken muhtemelen bazı 'tanımsız özellik adını okuyamıyor'.
Jamie Twells

İkisinin bir kombinasyonu ne olacak? Kullanıcıların arkadaşları olduğunu varsayarsak. / kullanıcılar / Kyle / arkadaşlar? name = Fred. Kyle mevcut değil, bu yanıt 404 olur mu? Yoksa 200 olur muydu, çünkü kyle'yi tam olarak umursamıyoruz, sadece fred adında arkadaşlarını aramayı umuyoruz?
JSextonn

Geçersiz bir istek olduğu için 404 verecek IMO: Kyle mevcut değil, bu yüzden arkadaşlarını aramak da mümkün değil.
Justus Romijn

23

Kaynağın var olması bekleniyor, ancak boş olabilirse, şeyin boş olduğunu gösteren bir temsil ile sadece 200 OK elde etmenin daha kolay olabileceğini iddia ederim.

Bu yüzden / şeyler, hiçbir şey olmayan bir 204 yerine {"Items": []} ile 200 OK döndürmeyi tercih ederdim, çünkü bu şekilde 0 öğeli bir koleksiyon, bir veya daha fazla öğe.

204 gerçekten PUT ve DELETE için hiçbir içerik bırakacaktı, burada gerçekten yararlı bir temsil yoktur.

/ Thing / 9'un gerçekten olmaması durumunda, 404 uygundur.


1
RPC adı verilen daha soyut bir form kullanarak bir API'ye karşı programlamayı tercih ettiğiniz anlaşılıyor. Fiilleri ve kaynak tabanlı bir url'yi yakından izleyerek kaynaklara erişmek yerine customers/1/addressbook, RPC yolu, bir uç noktayı çağırmak GetCustomerAddressBookve verileri almak veya esasen null olmaktır ve HTTP'nin karmaşıklıkları hakkında çok fazla endişelenmek zorunda değildir. Her ikisinin de artıları ve eksileri var.
Muffin Man

2
Muffin Man, REST veya RPC'yi tercih edip etmediğimi veya HTTP GET isteğine hangi durum kodunun döndürüleceği hakkında bir tartışma ile ilgili olduğunu nasıl bildiğinizden emin değilim.
j0057

204 kullanırken bazı korkunç önbellek sorunları yaşadım. Chrome, isteği garip bir şekilde ele alacak ve ağda hiçbir şey göstermeyecek ve önceki sonucu önbelleğe alacaktı. Dünyadaki önbelleksiz üstbilgilerle bile. Bu yanıta katılıyorum, 200 kullanıcıya boş bir dizi / nesne ile en iyi gibi görünüyor.
Jack

22

Önceki projelerde, 404 kullandım. Kullanıcı 9 yoksa, nesne bulunamadı. Bu nedenle 404 Bulunamadı uygundur.

Nesne var, ancak veri yok, 204 İçerik uygun olmaz. Bence sizin durumunuzda nesne mevcut değil .


14

W3 postasına göre ,

200 TAMAM

İstek başarılı oldu. Yanıtla döndürülen bilgiler, istekte kullanılan yönteme bağlıdır

202 Kabul edildi

İstek işleme koyulmak üzere kabul edildi, ancak işleme tamamlanmadı.

204 İçerik Yok

Sunucu isteği yerine getirdi, ancak varlık gövdesini döndürmesi gerekmiyor ve güncellenmiş metainformasyonu geri vermek isteyebilir.

400 Hatalı İstek

İstek, hatalı biçimlendirilmiş sözdizimi nedeniyle sunucu tarafından anlaşılamadı. İstemci, değişiklik yapmadan isteği tekrarlamamalıdır

401 Yetkisiz

İstek için kullanıcı kimlik doğrulaması gerekiyor. Yanıt bir WWW-Authenticate başlık alanı içermelidir ZORUNLU

404 Bulunamadı

Sunucu, İstek URI'sı ile eşleşen bir şey bulamadı. Durumun geçici mi yoksa kalıcı mı olduğuna dair hiçbir belirti verilmez


W3 gönderisi HTTP durum kodlarıyla ilgilidir. HTTP REST ile aynı değil. REST çoğunlukla taşıma protokolü olarak HTTP kullanır. 404 bir HTTP aktarım hata kodudur. REST HTTP ile aynıysa, HTTP olarak adlandırılmamalı mı?
anneb

1
@anneb Dediğin gibi REST HTTP kullanıyor, bu yüzden bu cevap tamamen mantıklı. REST HTTP değil, REST yine de bir protokol değil. Bu yanıtın anlamlı olmaması için REST'in aynı (veya HTTP ile aynı) olması gerekmez.
Koray Tugay

@Koray Tugay: google arama ayrıca http kullanır, bu nedenle bu cevaba göre google arama hiçbir şey arama ile eşleşmiyorsa http durumu 404 yanıt vermelidir?
anneb

@anneb Google Arama RESTful uygulamasından bahsediyor mu? Ben öyle düşünmüyorum .. Dolayısıyla cevap hayır olacak. Bir tavşan deliğine düşmek yerine orijinal soruya ve bu cevaba geri dönüyoruz. Google Arama bir gün RESTful API oluşturursa (veya belki de zaten var, bilmiyorum) 204 No Contentsonuç bulamadığında geri dönebilir . Değil 404, sizin için bir sonucu var, ancak içeriği yok ..
Koray Tugay

13

Özetlemek ya da basitleştirmek,

2xx: İsteğe bağlı veriler: İyi biçimlendirilmiş URI: Ölçütler URI'nin bir parçası değildir: @RequestBody ve @RequestParam içinde belirtilebilecek ölçütler isteğe bağlı ise 2xx'e yol açmalıdır. Örnek: ada / duruma göre filtrele

4xx: Beklenen veriler: İyi biçimlendirilmemiş URI: Ölçütler URI'nin bir parçasıdır: Yalnızca @PathVariable'da belirtilebilecek ölçütler zorunluysa 4xx'e yol açmalıdır. Örnek: benzersiz kimliğe göre arama.

Bu nedenle, sorulan durum için: "kullanıcılar / 9" 4xx (muhtemelen 404) olacaktır. Ancak "kullanıcılar? Name = superman" için 2xx (muhtemelen 204) olmalıdır


12

Sorulan iki soru var. Biri başlıkta ve diğeri örnekte. Bunun kısmen hangi cevabın uygun olduğu konusundaki anlaşmazlık miktarına yol açtığını düşünüyorum.

Soru başlığı boş veriler hakkında sorular sorar. Boş veriler hala verilerdir, ancak verilerle aynı değildir. Yani bu bir sonuç kümesi, yani bir liste,/users . Bir liste boşsa, yine de bir listedir, bu nedenle 204 (İçerik Yok) en uygunudur. Siz sadece bir kullanıcı listesi istediniz ve bir tane ile birlikte verildiniz, sadece içeriğiniz yok.

Bunun yerine verilen örnek belirli bir nesneyi, kullanıcıyı, soruyor /users/9. 9 numaralı kullanıcı bulunamazsa, hiçbir kullanıcı nesnesi döndürülmez. Belirli bir kaynak (bir kullanıcı nesnesi) istediniz ve bulunamadığı için bu kaynağı vermediniz, bu nedenle 404 uygundur.

Ben bunu çözmek için yolu herhangi bir koşullu ifade eklemeden beklediğiniz şekilde kullanabilirsiniz, sonra 204 kullanın aksi takdirde 404 kullanın olduğunu düşünüyorum.

Örneklerimde, içeriğe sahip olup olmadığını kontrol etmeden boş bir liste üzerinde yineleme yapabilirim, ancak bir şey kırmadan veya boş olup olmadığını görmek için bir kontrol eklemeden boş bir nesnede kullanıcı nesnesi verilerini görüntüleyemiyorum.

Elbette ihtiyaçlarınıza uygun, ancak bu başka bir iş parçacığı için bir tartışma ise null nesne desenini kullanarak bir nesneyi döndürebilirsiniz.


9

Soruya baktıktan sonra 404neden kullanmamalısınız ?

Dayanarak RFC 7231 doğru durum kodu204

Yukarıdaki anwsers 1 küçük yanlış anlama fark ettim:

1.- kaynak: /users

2.- /users/8kaynak değil, bu: /usersroute parametresine sahip kaynak8 , tüketici belki bunu fark edemez ve farkı bilmiyor, ancak yayıncı bunu biliyor ve bilmeli! ... bu yüzden tüketiciler için doğru bir yanıt vermelidir. dönem.

yani:

Kaynaklar bulunduğundan RFC: 404 yanlıştır /users, ancak parametre kullanılarak yürütülen mantık bir yanıt olarak geri dönmek için 8herhangi contentbir sonuç bulamadı , bu nedenle doğru cevap:204

Buradaki ana nokta şudur: 404Kaynak bile dahili mantığı işlemek için bulunamamıştır

204a: Kaynağı buldum, mantık yürütüldü ama rota parametresinde verilen kriterlerinizi kullanarak herhangi bir veri bulamadım, bu yüzden size bir şey döndüremiyorum. Üzgünüm, kriterlerinizi doğrulayın ve beni tekrar arayın.

200: Tamam kaynak bulundu, mantık yürütüldü (ben bir şey geri dönmek zorunda değilim bile) bu almak ve iradesine kullanmak.

205: (bir GET yanıtının en iyi seçeneği) Kaynağı buldum, mantık yürütüldü, sizin için bazı içeriğim var, iyi kullan, oh bu arada bir görünümde paylaşacaksanız lütfen görünümü yenileyin görüntülemek.

Umarım yardımcı olur.


8

Mevcut cevapların üzerinde durmadığı şey, yol parametrelerini veya sorgu parametrelerini kullanmanın fark yaratmasıdır.

  • Yol parametreleri durumunda, parametre kaynak yolunun bir parçasıdır. Bu durumda /users/9yanıt, 404bu kaynağın bulunamamış olması gerekir . /users/9kaynaktır ve sonuç olağandışıdır ya da bir hata mevcut değildir. Bu bir monad değil .
  • Sorgu parametreleri durumunda, parametre kaynak yolunun bir parçası değildir. Böyle bir durumda /users?id=9, yanıt 204kaynak /usersbulunmuş olmalı ancak herhangi bir veri döndürememelidir. Kaynak /usersvar ve sonuç n-ary, boş olsa bile var. Eğer idtektir, bu ise bir monad.

Yol parametrelerinin veya sorgu parametrelerinin kullanılıp kullanılmayacağı kullanım durumuna bağlıdır. Zorunlu, normatif veya tanımlayıcı argümanlar için yol parametrelerini ve isteğe bağlı, normatif olmayan veya ilişkilendirme argümanları (sayfalama, harmanlama yerel ayarı ve benzeri) için sorgu parametrelerini tercih ederim. REST API, ben kullanırım /users/9değil /users?id=9gibi "alt kayıtları" almak için özellikle çünkü olası yuvalama /users/9/ssh-keys/0ilk kamu ssh anahtarı almak için ya da /users/9/address/2üçüncü posta adresini almak için.

404 kullanmayı tercih ediyorum. İşte nedeni:

  • Tekli (1 sonuç) ve n-ary (n sonuç) yöntemleri için yapılan çağrılar, iyi bir sebep olmaksızın değişmemelidir. Mümkünse aynı yanıt kodlarına sahip olmayı seviyorum. Beklenen sonuçların sayısı elbette bir farktır, örneğin vücudun bir nesne (tekli) veya bir nesne dizisi (n-ary) olmasını beklersiniz.
  • N-ary için, bir dizi döndürürdüm ve sonuç yoksa, hiçbir set (belge yok) döndürmezdim, boş bir set (boş belge, JSON'daki boş dizi veya XML'deki boş öğe gibi) döndürürdüm ). Yani, hala 200 ama sıfır kaydı var. Bu bilgiyi vücuttan başka telin üzerine koymak için hiçbir neden yoktur.
  • 204bir voidyöntem gibidir. Ben bunu kullanmak ister GETyalnızca, POST, PUT, ve DELETE. GETTanımlayıcıların yol parametreleri değil sorgu parametreleri olduğu durumlarda bir istisna yapıyorum .
  • Kayıt bulamıyorum gibidir NoSuchElementException, ArrayIndexOutOfBoundsExceptionveya yoksa, yani, bu bir istemci hatası var bir kimliği kullanarak istemci tarafından neden böyle bir şey.
  • Kod perspektifinden bakıldığında, 204kodda önlenebilecek ek bir dal anlamına gelir. İstemci kodunu karmaşıklaştırır ve bazı durumlarda sunucu kodunu da karmaşık hale getirir (varlık / model monad'larını veya düz varlıkları / modelleri kullanmanıza bağlı olarak; ve varlık / model monad'larından uzak durmanızı şiddetle tavsiye ederim, çünkü kötü hatalara neden olabilir Monadın bir operasyonun başarılı olduğunu düşünüyorsunuz ve aslında başka bir şey iade etmeniz gerektiğinde 200 veya 204'e dönüyorsunuz).
  • 2xx, sunucunun istemcinin istediği şeyi yaptığını ve 4xx sunucunun istemcinin istediği şeyi yapmadığını ve istemcinin hatası olduğunu belirtirse, istemci kodunu yazmak ve anlamak daha kolaydır. İstemcinin id tarafından istendiği kaydı vermemesi istemcinin hatasıdır, çünkü istemci var olmayan bir kimlik istemiştir.

Son fakat en az değil: Tutarlılık

  • GET /users/9
  • PUT /users/9 ve DELETE /users/9

PUT /users/9ve başarılı bir güncelleme veya silme durumunda DELETE /users/9zaten geri dönmek zorundasınız 204. Öyleyse, 9 numaralı kullanıcının mevcut olmaması durumunda ne dönmeleri gerekir? Kullanılan HTTP yöntemine bağlı olarak aynı durumun farklı durum kodlarıyla sunulması anlamsızdır.

Ayrıca, normatif değil, kültürel bir sebep: Eğer projede olacak bir sonraki şey 204için kullanılırsa GET /users/9, birileri geri dönmenin 204n-ary yöntemleri için iyi olduğunu düşünüyor . Ve bu müşteri kodunu zorlaştırıyor, çünkü sadece 2xxvücudu kontrol etmek ve sonra kodunu çözmek yerine , müşteri şimdi özel olarak kontrol etmek zorunda 204ve bu durumda vücudu kodlamayı atlamak zorunda. Bud müşteri bunun yerine ne yapıyor? Boş bir dizi oluşturulsun mu? Öyleyse neden telde yok? İstemci boş diziyi oluşturursa, 204 bir aptal sıkıştırma biçimidir. İstemci nullbunun yerine kullanırsa , tamamen farklı bir solucan kutusu açılır.



3

204 daha uygundur. Özellikle web sitenizin güvenli olduğundan emin olmak için bir uyarı sisteminiz olduğunda, 404 uyarısının arka uç hataları veya normal istekler olduğunu ancak yanıtın boş olduğunu bilmediğiniz için bu durumda 404 karışıklığa neden olur.


Bir arka uç hatanız varsa 404'ü iade etmemelisiniz.
appalling22

3

Bence, ikisi de gerçekten uygun değil. Daha önce de söylendiği gibi - örneğin @anneb tarafından, ben de sorunların bir kısmının RESTful hizmetiyle ilgili bir durumu taşımak için bir HTTP yanıt kodu kullanmaktan kaynaklandığını düşünüyorum. REST hizmetinin kendi işlenmesi hakkında söylemesi gereken her şey, REST'e özgü kodlarla taşınmalıdır.

1

HTTP sunucusu, gönderilen bir isteği yanıtlamaya hazır herhangi bir hizmet bulursa, HTTP 404 ile yanıt vermemelidir - sonunda, sunucu tarafından açıkça belirtilmedikçe, sunucu tarafından bir şey bulundu. isteği işleyen hizmet.

Bir an için aşağıdaki URL'yi varsayalım: http://example.com/service/return/test.

  • Durum A, sunucunun “sadece dosya sistemindeki dosyayı aramasıdır”. Eğer yoksa 404, doğrudur. Aynı şey, tam olarak bu dosyayı sunmak için bir tür hizmet isterse ve bu hizmet, bu adın hiçbirinin olmadığını söyler.
  • B durumunda, sunucu "gerçek" dosyalarla çalışmaz, ancak aslında istek başka bir hizmet tarafından işlenir - örneğin bir tür geçici sistem. Burada, sunucu, kaynak hakkında hiçbir şey bilmediği için kaynağın varlığı hakkında herhangi bir iddiada bulunamaz (onu işleyen servis tarafından belirtilmedikçe).

Hizmetten açıkça farklı bir davranış gerektiren herhangi bir yanıt olmadan, HTTP sunucusu yalnızca 3 şey söyleyebilir:

  • 503 isteği işlemesi gereken servis çalışmıyorsa veya yanıt vermiyorsa;
  • 200 Aksi takdirde HTTP sunucusu aslında isteği karşılayabilir - hizmetin daha sonra ne söyleyeceği önemli değil;
  • 400ya da 404böyle bir hizmetin olmadığını (“var ama çevrimdışı” yerine) ve başka bir şey bulunmadığını belirtmek için.

2

Eldeki soruya geri dönmek için: Bence en temiz yaklaşım, bir HTTP'nin daha önce söylenenden başka herhangi bir yanıt kodu kullanmamak olduğunu düşünüyorum. Hizmet varsa ve yanıt veriyorsa, HTTP kodu 200 olmalıdır. Yanıt, hizmetin ayrı bir başlıkta döndürülen durumu içermelidir - burada, hizmet şunu söyleyebilir:

  • REST:EMPTYörneğin, sth araması istendiğinde. ve bu araştırma boş döndü;
  • REST:NOT FOUNDsth için özel olarak istenip istenmediği. “ID benzeri” - bir dosya adı veya ID veya giriş No. 24'e göre bir kaynak vb.) - ve bu belirli kaynak bulunamadı (genellikle, belirli bir kaynak istendi ve bulunamadı);
  • REST:INVALID gönderilen talebin herhangi bir kısmı servis tarafından tanınmıyorsa.

(Bunların HTTP yanıt kodlarıyla aynı değerlere veya ifadelere sahip olmalarına rağmen, tamamen farklı olduklarını işaretlemek için bunları “REST:” ile ön eklediğimi unutmayın)

3

Yukarıdaki URL'ye geri dönelim ve hizmetin HTTP sunucusuna bu isteğin kendisini ele almadığını ancak ilettiği iletiyi gösterdiği B durumunu inceleyelim SERVICE. HTTP sadece ne tarafından geri verildiğini sunar SERVICE, o return/testbölümün kendisi tarafından ele alındığı gibi bir şey bilmez SERVICE. Bu hizmet çalışıyorsa, HTTP , isteği işleyecek bir şey bulduğu200 gibi dönmelidir .

Tarafından döndürülen SERVICE(ve yukarıda belirtildiği gibi, ayrı bir başlıkta görmek isteyen) durum, gerçekte hangi işlemin beklendiğine bağlıdır:

  • eğer return/testbelirli bir kaynak için sorar: varsa, durumuyla iade REST:FOUND; bu kaynak yoksa, geri dönün REST:NOT FOUND; bir REST:GONEzamanlar var olduğunu ve geri dönmeyeceğini bildiğimiz takdirde geri dönmek için uzatılabilir ve REST:MOVEDeğer Hollywood'a gittiğini bilersek
  • eğer return/testkabul edilir bir arama veya filtre benzeri operasyon: sonuç kümesi boşsa, istenen türde ve bir durum değerlendirmesi boş kümesi döndürmek REST:EMPTY; istenen türde bir sonuç kümesi veREST:SUCCESS
  • eğer return/testbir işlem tarafından tanınmıyorsa SERVICE: REST:ERRORtamamen yanlışsa (örneğin yazım hatası gibi retrun/test) veya REST:NOT IMPLEMENTEDdaha sonra yapılması planlanıyorsa geri dönün .

4

Bu ayrım iki farklı şeyi karıştırmaktan çok daha temiz. Ayrıca hata ayıklamayı kolaylaştıracak ve hiç değilse biraz daha karmaşık işleyecektir.

  • Bir HTTP 404 döndürülürse, sunucu bana “Ne hakkında konuştuğumu bilmiyorum” der. İsteğimin REST kısmı tamamen iyi olsa da, tüm yanlış yerlerde par'Mach arıyorum.
  • Öte yandan, HTTP 200 ve REST: ERR bana hizmeti aldığımı ancak hizmete olan isteğimde yanlış bir şey yaptığımı söylüyor.
  • HTTP 200 ve REST'ten: BOŞLUK, yanlış bir şey yapmadığımı biliyorum - doğru sunucu, sunucu hizmeti buldu, hizmete doğru istek - ama arama sonucu boş.

özet

Sorun ve tartışma, HTTP yanıt kodlarının, sonuçları HTTP tarafından sunulan bir hizmetin durumunu veya sth'i belirtmek için kullanılmasından kaynaklanmaktadır. HTTP sunucusunun kapsamında değildir. Bu tutarsızlık nedeniyle, soru cevaplanamaz ve tüm görüşler çok fazla tartışmaya tabidir.

HTTP sunucusu tarafından değil, bir hizmet tarafından işlenen bir isteğin durumu GERÇEKTEN OLMAMALIDIR (RFC 6919) bir HTTP yanıt kodu tarafından verilmelidir. HTTP kodu SHOULD (RFC 2119) yalnızca HTTP sunucusunun kendi kapsamından verebileceği bilgileri içerir: yani, hizmetin isteği işlemek için bulunup bulunmadığı.

Bunun yerine, bir tüketiciye, talebi işleyen servise talebin durumu hakkında bir tüketiciyi anlatmak için farklı bir yol kullanılmalıdır. Benim teklifim bunu belirli bir başlık aracılığıyla yapmak. İdeal olarak, hem başlığın adı hem de içeriği, tüketicilerin bu yanıtlarla çalışmasını kolaylaştıran bir standarda uyar.


2

RFC7231 - sayfa59'a ( https://tools.ietf.org/html/rfc7231#page-59 ) göre 404 durum kodu yanıtının tanımı:

6.5.4. 404 Bulunamadı 404 (Bulunamadı) durum kodu, kaynak sunucunun hedef kaynak için geçerli bir temsil bulamadığını veya var olduğunu açıklamak istemediğini gösterir. 404 durum kodu, bu temsil eksikliğinin geçici mi yoksa kalıcı mı olduğunu göstermez; eğer kaynak sunucu, muhtemelen bazı yapılandırılabilir yollarla durumun kalıcı olacağını bilirse 410 (Gitti) durum kodu 404'ün üzerinde tercih edilir. Bir 404 yanıtı varsayılan olarak önbelleğe alınabilir; örn., yöntem tanımı veya açık önbellek kontrolleri tarafından aksi belirtilmedikçe ([RFC7234] Bölüm 4.2.2'ye bakınız).

Şüphe uyandıran en önemli şey, yukarıdaki bağlamda kaynağın tanımıdır. Aynı RFC'ye (7231) göre kaynağın tanımı:

Kaynaklar: HTTP isteğinin hedefine "kaynak" denir. HTTP bir kaynağın yapısını sınırlamaz; yalnızca kaynaklarla etkileşime girmek için kullanılabilecek bir arabirim tanımlar. Her kaynak, [RFC7230] Bölüm 2.7'de açıklandığı gibi Tekdüzen Kaynak Tanımlayıcısı (URI) ile tanımlanır. İstemci bir HTTP / 1.1 istek iletisi oluşturduğunda, hedef URI'yı ([RFC7230] Bölüm 5.3) 'de tanımlandığı gibi çeşitli formlardan birinde gönderir. Bir istek alındığında, sunucu hedef kaynak için etkili bir istek URI'sı yeniden oluşturur ([RFC7230] Bölüm 5.5). HTTP'nin bir tasarım amacı, kaynak anlamını istek yönteminden (Bölüm 4) ve birkaç istek değiştirici başlık alanından (Bölüm 5) sağlayarak mümkün olan kaynak tanımlamasını istek anlambiliminden ayırmaktır.

Benim durumumda 404 durum kodu boş GET isteğinde başarılı GET isteğinde kullanılmamalıdır.


2

Bu tür şeyler öznel olabilir ve her iki tarafta da ilginç ve çeşitli sağlam argümanlar vardır. Ancak [benim görüşüme göre] eksik veri için 404 döndürmek doğru değil . Bunu açıklığa kavuşturmak için basitleştirilmiş bir açıklama:

  • Talep: Biraz veri alabilir miyim lütfen?
  • Kaynak (API bitiş noktası): Bu isteği sizin için alacağım, burada [potansiyel verilerin yanıtını gönderir]

Hiçbir şey kırılmadı, bitiş noktası bulundu ve DB sorgulandı ve veri "başarıyla" döndü böylece tablo ve sütunlar bulundu!

Şimdi - "başarılı yanıt" ın veri olup olmadığı önemli değil, "potansiyel" verilerin yanıtını istediniz ve "potansiyel" verilerle yanıt verildi. Boş, boş vb. Geçerli verilerdir.

200, yaptığımız herhangi bir talebin başarılı olduğu anlamına gelir. Ben veri talep ediyorum, hiçbir şey HTTP / REST ile yanlış gitti ve veri (boş da olsa) döndü gibi benim "veri talebi" başarılı oldu.

200 döndürün ve her özel senaryo için garanti veren istek sahibinin boş verilerle ilgilenmesine izin verin!

Bu örneği düşünün:

  • İstek: 1234 kullanıcı kimliğine sahip "ihlaller" tablosunu sorgulayın
  • Kaynak (API bitiş noktası): Bir yanıt döndürür ancak veriler boştur

Boş olan bu veriler tamamen geçerlidir. Bu, kullanıcının herhangi bir ihlali olmadığı anlamına gelir. Bu 200, hepsi geçerli olduğu gibi, o zaman ben yapabilirim:

İhlalleriniz yok, yaban mersinli çörek var!

Bunu 404 olarak görüyorsanız ne söylersiniz? Kullanıcının ihlalleri bulunamadı mı? Şimdi, dilbilgisel olarak doğru, ancak REST dünyasında doğru değil, başarı ya da başarısızlık istekle ilgilidir. Bu kullanıcı için "ihlal" verileri başarıyla bulunabilir, sıfır ihlal vardır - geçerli bir durumu temsil eden gerçek bir sayı.


[Arsız not ..]

Başlığınızda, bilinçsizce 200'ün doğru yanıt olduğunu kabul ediyorsunuz:

Geçerli bir istek yerine boş bir veri için uygun REST yanıt kodu nedir?


Öznellik ve zor seçimlerden bağımsız olarak hangi durum kodunun kullanılacağını seçerken göz önünde bulundurmanız gereken bazı noktalar şunlardır:

  1. Tutarlılık . "Veri yok" için 404 kullanırsanız , yanıt her veri döndürmediğinde bunu kullanın .
  2. Aynı durumu birden fazla anlam için kullanmayın . Bir kaynak bulunamadı zaman 404 dönerseniz (örneğin API bitiş noktası vb yok) sonra yok ayrıca döndürülen hiçbir veri için kullanabilirsiniz. Bu sadece yanıtlarla uğraşmayı bir acı haline getirir.
  3. Bağlamı dikkatlice düşünün . "Talep" nedir? Neyi başarmaya çalıştığını söylüyorsun?

1

Yanıt içeriğini, istemcinin açmasına ve mantığı buna göre açmasına izin veren ortak bir numara ile kodlayın. Müşterinizin "veri bulunamadı" 404 ile "web kaynağı bulunamadı" 404 arasındaki farkı nasıl ayırt edeceğinden emin değilim? Birinin Z / 9 kullanıcısına göz atmasını istemiyorsunuz ve istemcinin istek geçerliymiş gibi merak etmesini istiyor ama veri döndürülmüyor.


1

Neden 410 kullanmıyorsunuz? İstenen kaynağın artık mevcut olmadığını ve istemcinin sizin durumunuzda bu kaynak için hiçbir zaman istekte bulunmaması beklendiğini gösterir users/9.

410 hakkında daha fazla bilgiyi burada bulabilirsiniz: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


2
'müşterinin hiçbir zaman bir talepte bulunmaması' - ve bu kullanıcı daha sonra oluşturulursa, cevabınız bu kullanıcının asla var olmayacağını garanti edebileceğinizi gösterir, bu çok cesur bir varsayım ve muhtemelen yanlış
Holly

Holly ne dedi. Konuya eklemek için: Kullanıcının var olması ve silinmesi durumunda bile 410 yanlıştır, çünkü kullanıcı silinmezse ne olur? (Hangi tür özel bir durum daha sonra yaratılır.)
Christian Hujer

çünkü 410 kalıcı bir durum olmalıdır. restapitutorial.com/httpstatuscodes.html
Akostha

1

Bu kadar basit ve iyi tanımlanmış bir şeyin "görüşe dayalı" hale gelmesi üzücü.

Bir HTTP sunucusu, statik bir web sayfası, arama sonuçlarının listesi, diğer varlıkların listesi, bir şeyin json açıklaması, medya dosyası vb. Gibi herhangi bir içerik için soyutlama olan "varlıkları" bilir.

Bu tür her bir varlığın benzersiz bir URL ile tanımlanması beklenir, ör.

  • / user / 9 - tek bir varlık: bir USER ID = 9
  • / users - tek bir varlık: tüm kullanıcıların bir listesi
  • /media/x.mp3 - tek bir varlık: x.mp3 adında bir medya DOSYASI
  • / search - tek bir varlık: sorgu parametrelerine dayalı dinamik bir İÇERİK

Bir sunucu verilen URL'ye göre bir kaynak bulursa, içeriğinin ne olduğu önemli değildir - 2G veri, boş, {}, [] - var olduğu sürece 200 olur. Ancak böyle bir varlık sunucu tarafından bilinmeyen, 404 "Bulunamadı" dönmek bekleniyor.

Bir karışıklık, uygulamanın belirli bir yol şekli için bir işleyici varsa, bir hata olmamasını düşünen geliştiricilerden kaynaklanıyor gibi görünüyor. HTTP protokolünün gözünde, sunucuda eşleşen bir varlık olmadığı sürece sunucunun iç kısımlarında ne olduğu (yani varsayılan yönlendiricinin yanıt vermesi veya belirli bir yol şekli için bir işleyici olup olmadığı) önemli değildir. istenen içeriği (talep edilen MP3 dosyası, web sayfası, kullanıcı nesnesi vb.) (geçerli içeriği (boş veya başka bir şekilde) döndürür) 404 (veya 410 vb.) olmalıdır.

Başka bir karışıklık noktası "veri yok" ve "varlık yok" civarındadır. Birincisi bir varlığın içeriği ve ikincisi varlığı hakkındadır.

Örnek 1:

  • Veri yok: / kullanıcı 200 OK döndürüyor, gövde: [] çünkü henüz kimse kayıtlı değil
  • Varlık yok: / kullanıcı yolu / kullanıcı olmadığı için 404 değerini döndürüyor

Örnek 2:

  • Veri yok: / kullanıcı / 9 dönüşü döndürüyor 200 TAMAM, gövde: {}, çünkü kullanıcı kimliği = 9 kişisel verilerini hiç girmedi
  • Varlık yok: / user / 9, kullanıcı kimliği = 9 olmadığından 404 değerini döndürüyor

Örnek 3:

  • Veri yok: / search? Name = Joe 200 OK [] döndürüyor, çünkü DB'de Joe yok
  • Varlık yok: / search? Name = Joe yol / arama olmadığı için 404 döndürüyor

0

404 yanıt olarak veri olmadığı için geri dönerseniz herhangi bir müşteri için çok kafa karıştırıcı olacaktır.

Benim için, boş bir gövdeye sahip olan Yanıt Kodu 200, her şeyin mükemmel olduğunu anlamak için yeterli, ancak gereksinimlere uyan veri yok.



0

Birçok kişi tarafından belirtildiği gibi, 404 yanıltıcıdır ve istek uri mevcut değilse veya talep edilen uri istenen kaynağı alamıyorsa istemcinin ayrım yapmasına izin vermez.

200 durumunun kaynak verilerini içermesi beklenir - bu yüzden doğru seçim değildir. 204 durumu tamamen başka bir şey anlamına gelir ve GET isteklerine yanıt olarak kullanılmamalıdır.

Var olan diğer tüm durumlar bir nedenden ötürü geçerli değildir.

Bu konunun birçok yerde tartışıldığını gördüm. Benim için, konu etrafındaki karışıklığı ortadan kaldırmak için özel bir başarı durumuna ihtiyaç olduğu acı verici bir şekilde açık. " 209 - Görüntülenecek kaynak yok " gibi bir şey .

Bu bir 2xx durumu olacaktır, çünkü bir kimlik bulamamak bir istemci hatası olarak düşünülmemelidir (istemciler sunucunun DB'sindeki her şeyi biliyorsa, sunucuya herhangi bir şey sormaları gerekmezdi, değil mi?). Bu özel durum, diğer durumlarla tartışılan tüm sorunları ele alacaktır.

Tek soru şudur: RFC'nin bunu standart olarak kabul etmesini nasıl sağlayabilirim?

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.