Başarısız doğrulama veya geçersiz kopya için REST HTTP durum kodları


826

REST tabanlı bir API ile bir uygulama inşa ediyorum ve her istek için durum kodları belirtiyorum noktasına geldim.

Doğrulama işlemi başarısız olan veya bir isteğin veritabanımdaki kopyayı eklemeye çalıştığı durumlarda hangi durum kodunu göndermeliyim?

Http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html adresine baktım ancak hiçbiri doğru gözükmüyor.

Durum kodlarını gönderirken yaygın bir uygulama var mı?



14
Httpstatus.es'yi açın , Sağ Tıklayın >> Pin Sekmesi: P
Salman von Abbas

Yanıtlar:


780

Giriş doğrulama hatası için: 400 Hatalı İstek + isteğe bağlı açıklamanız. Bu, " RESTful Web Services " kitabında önerilmektedir . Çift başvuru için: 409 Çatışma


Haziran 2014 Güncellemesi

İlgili şartname eskiden RFC2616 400 (Yanlış Request) kullanımını verdi ziyade dar olarak

İstek, hatalı biçimlendirilmiş sözdizimi nedeniyle sunucu tarafından anlaşılamadı

Bu yüzden anlambilimsel hatalar için uygunsuz olduğu iddia edilmiş olabilir . Ama artık değil; Haziran 2014'ten beri , önceki RFC2616'nın yerini alan ilgili standart RFC 7231 , 400 (Kötü İstek) kullanımını daha geniş

sunucu, istemci hatası olarak algılanan bir şey nedeniyle isteği işleyemiyor veya işlemeyecek


3
Evet, istek gövdesi sözdiziminin bir parçasıdır.
deamon

62
Kötü talep, bu tür sorunlara kesinlikle en yaygın yanıttır. Diğer tek alternatif 422 İşlenemez Varlıktır. Aslında WebDav'dan geliyor, ancak IANA'ya kayıtlı herhangi bir durum kodunu yeniden kullanmak mükemmel bir şekilde geçerli.
Darrel Miller

19
Peki, sunucunun ayrıştıramadığı hatalı biçimlendirilmiş veriler ile bir doğrulama hatası arasında nasıl ayrım yapıyorsunuz? Bir müşteri bu iki yanıtı tamamen farklı şekilde ele alacaktır. Doğrulama için muhtemelen hataları kullanıcıya göstereceklerdir. Gerçekten "hatalı biçimlendirilmiş veriler" için, hatayı günlüğe kaydeder, böylece isteği oluşturan yöntemdeki hata düzeltilebilir.
Josh Noe

18
Belirtmekle birlikte, something perceived to be a client errorbu paragrafta verilen tüm örnekler mantıksal hatalar değil, HTTP protokolünün ihlalidir: sözdizimi, çerçeveleme, yönlendirme. Bu nedenle, HTTP spesifikasyonunun uygulama düzeyinde başarısız doğrulama için 400'e izin vermediğini düşünüyorum .
Dima Tisnek

2
neden 422 - İşlenemez varlık kullanmıyorsunuz? Bana daha mantıklı görünüyor
java_geek

278
  • Doğrulama başarısız: 403 Yasak ("Sunucu isteği anladı, ancak yerine getirmeyi reddediyor"). Popüler düşüncenin aksine, RFC2616 "403 sadece başarısız kimlik doğrulaması için tasarlanmıştır" değil, "403: Ne istediğini biliyorum, ama bunu yapmayacağım" demiyor. Bu koşul kimlik doğrulaması nedeniyle olabilir veya olmayabilir.
  • Bir kopya eklemeye çalışılıyor: 409 Çakışma ("Kaynağın geçerli durumu ile bir çakışma nedeniyle istek tamamlanamadı.")

Yanıt başlıklarında ve / veya gövdesinde kesinlikle daha ayrıntılı bir açıklama yapmalısınız (örneğin, özel bir başlıkla - X-Status-Reason: Validation failed).


17
@deamon: Bu şartname değil , Wikipedia, yani "HTTP durum kodlarının ne anlama geldiği" konusunda birinin görüşü; sayfanın temel olarak "Apache'nin 403 ile yaptığı şey budur, IIS'nin 403 ile yaptığı şey budur" diyor ve hiçbir yerde resmi RFC'yi referans almıyor. "403 Apache ne derse desin" diye tekrar ediyor gibi görünüyorsun. DEĞİL. Gerçek RFC (başka birinin uygulaması değil, IIS'nin uygulaması değil, Apache'nin uygulaması değil, ilgili belge) burada: w3.org/Protocols/rfc2616/rfc2616-sec10.html
Piskvor

57
"10.4.4 403 Yasak Sunucu isteği anladı, ancak yerine getirmeyi reddediyor. Yetkilendirme yardımcı olmayacak ve istek tekrarlanmamalıdır. İstek yöntemi HEAD değilse ve sunucu isteğin neden yapmadığını halka duyurmak istiyorsa yerine getirildiğinde, varlıktaki ret nedenini açıklamalıdır. Sunucu bu bilgileri istemciye sunmak istemiyorsa, bunun yerine 404 durum kodu (Bulunamadı) kullanılabilir. " Ben orada hiçbir vurgu görüyorum ("OMUZ / OMUZ DEĞİL" vurgu değil RFC 2119 anahtar kelimeler vardır); RFC'lerin değil, “yasak” ne demek olduğu fikriniz budur.
Piskvor binadan ayrıldı

10
Bu yanıtı seviyorum, ama yine de küçük bir sorun görüyorum. Spesifikasyona göre , bir 403 iade edildiğinde , "istek tekrarlanmamalıdır". Ancak, 409 " döndürülmesine yalnızca kullanıcının çakışmayı çözebileceği ve isteği yeniden gönderebileceği beklenilen durumlarda" izin verilir. Yinelenen bir durumda, bence 403 daha uygun olur, çünkü çatışmayı gerçekten çözemezsiniz (kaynağın önceki örneğini silme hariç).
pablobm

2
Hata mesajının kendisi için neden ifadesini değiştirmeniz gerekir, bu nedenle üstbilgiyi göndermek HTTP/1.0 403 Form validation errorsen temiz yoldur.
aleemb

6
IMO, 422 "İşlenemez Varlık" çok daha mantıklı. Benim akıl sunucu değil o olduğunu reddediyor sunucu işte, isteği yerine getirmek için can not isteği yerine.
tybro0103

225

Durum kodu 422, "İşlenemez Varlık" öneririm .

11.2. 422 İşlenemeyen Varlık

422 (İşlenemeyen Varlık) durum kodu, sunucunun istek varlığının içerik türünü anladığı (bu nedenle 415 (Desteklenmeyen Medya Türü) durum kodu uygun değildir) ve istek varlığının sözdiziminin doğru olduğu (dolayısıyla 400 (Hatalı İstek) anlamına gelir. ) durum kodu uygun değil), ancak içerdiği talimatları işleyemedi. Ö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 koşulu oluşabilir.


11
Elbette bu bir HTTP durum kodudur, bkz. İana.org/assignments/ http-status- codes . RFC 2616'da tanımlananlardan daha fazla durum kodu var.
Julian Reschke

7
WebDAV bir HTTP uzantısıdır . "Web Dağıtılmış Yazma ve Sürüm Oluşturma (WebDAV) için HTTP Uzantıları" Durum kodu 422 bir http durum kodu değil, bir http durumunun durum kodudur.
deamon

16
deamon, bu mantıklı değil. HTTP, yeni kodların nasıl tanımlanacağını tanımlar ve WebDAV bunu yapar. Bir sebepten dolayı durum kodu kaydı var.
Julian Reschke

14
FYI - 422: 11.2'nin RFC açıklaması. 422 İşlenemeyen Varlık 422 (İşlenemeyen Varlık) durum kodu, sunucunun istek varlığının içerik türünü anladığı (bu nedenle 415 (Desteklenmeyen Medya Türü) durum kodu uygun değildir) ve istek varlığının sözdiziminin doğru olduğu (dolayısıyla 400 (Hatalı İstek) durum kodu uygun değil) ancak içerdiği talimatları işleyemedi. Ö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 koşulu oluşabilir.
Steve Kallestad

6
Ve iş parçacıklarının süresi dolmaz. Hayatta kalmaları gerekir veya en iyi google arama sonuçları yanlış olmaya başlar.
James Billingham

81

200,300, 400, 500 çok geneldir. Genel istiyorsanız, 400 tamam.

422 artan sayıda API tarafından kullanılıyor ve hatta Rails tarafından kutunun dışında kullanılıyor.

API'nız için hangi durum kodunu seçerseniz seçin, birileri katılmayacaktır. Ama 422'yi tercih ediyorum çünkü '400 + metin durumu' çok genel. Ayrıca, JSON için hazır bir ayrıştırıcıdan yararlanmıyorsunuz; bunun aksine, JSON yanıtı olan bir 422 çok açıktır ve çok sayıda hata bilgisi iletilebilir.

JSON yanıtından bahsetmişken, bu durum için Rails hata yanıtında standartlaşma eğilimindeyim:

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

Bu biçim, 'hata raporlama zenginliği' açısından desteklenmesi gereken en karmaşık durumu düşündüğüm form doğrulaması için mükemmeldir. Hata yapınız bu ise, muhtemelen tüm hata raporlama ihtiyaçlarınızı karşılayacaktır.


2
Argler arasındaki etkileşimlerden kaynaklanan hatalar ne olacak? Yani, arg1geçerlidir ve arg2geçerlidir, ancak ikisinin gönderilen belirli değerlerle kombinasyonu geçerli değildir.
Jonah

1
Ben bunu düşünmezdim; sadece ilişkiye sahip gibi görünen birini seçin.
sethcall

hatta her iki argümanda da hata olabilir. Bir kullanıcı olarak, her bir alandaki çelişkili hatayı görmek istediğimi düşünüyorum.
snuggles

Güzel!. açık
bhathiya-perera

46

200

Ugh ... (309, 400, 403, 409, 415, 422) ... başarılı bir HTTP isteği için başarısız bir REST çağrısı için en iyi dönüş kodunun ne olduğunu tahmin etmeye, tartışmaya ve standartlaştırmaya çalışan birçok cevap .

Öyle yanlış HTTP durum kodları ve DİNLENME durum kodlarını karıştırmak için.

Bununla birlikte, onları karıştıran birçok uygulama gördüm ve birçok geliştirici benimle aynı fikirde olmayabilir.

HTTP dönüş kodları HTTP Requestkendisiyle ilgilidir. Bir REST çağrısı, Köprü Metni Aktarım Protokolü isteği kullanılarak yapılır ve çağrılan REST yönteminin kendisinden daha düşük bir düzeyde çalışır. REST bir kavram / yaklaşımdır ve çıktısı bir iş / mantıksal sonucudur, HTTP sonuç kodu ise bir aktarımdır .

Örneğin, / users / komutunu çağırdığınızda "404 Bulunamadı" ifadesinin döndürülmesi karıştırılabilir, çünkü bu şu anlama gelebilir:

  • URI yanlış (HTTP)
  • Kullanıcı bulunamadı (REST)

"403 Yasak / Erişim Reddedildi":

  • Özel izin gerekiyor. Tarayıcılar kullanıcı / parola sorarak bunu kaldırabilir. (HTTP)
  • Sunucuda yanlış erişim izinleri yapılandırılmış. (HTTP)
  • Kimlik doğrulamanız gerekiyor (REST)

Ve liste '500 Sunucu hatası' (Apache / Nginx HTTP atılan hatası veya REST'te iş kısıtlaması hatası) veya diğer HTTP hataları vb. İle devam edebilir.

Koddan, hata nedeninin, HTTP (taşıma) hatasının veya REST (mantıksal) hatasının ne olduğunu anlamak zordur.

HTTP isteği fiziksel olarak başarıyla gerçekleştirilmişse , bulunan kayıt (lar) ne olursa olsun, her zaman 200 kod döndürmelidir. Çünkü URI kaynağı bulundu ve HTTP sunucusu tarafından işlendi. Evet, boş bir set döndürebilir. HTTP sonucu 200 olan boş bir web sayfası almak mümkün müdür, değil mi?

Bunun yerine bazı seçeneklerle 200 HTTP kodu döndürebilirsiniz:

  • bir şeyler ters giderse JSON sonucundaki "hata" nesnesi
  • Kayıt bulunamadığı takdirde boş JSON dizisi / nesnesi
  • Daha iyi bir kullanım için önceki seçeneklerle birlikte bir bool sonucu / başarı bayrağı.

Ayrıca, bazı internet sağlayıcıları isteklerinizi kesebilir ve size 404 HTTP kodu verebilir. Bu, verilerinizin bulunmadığı anlamına gelmez, ancak taşıma düzeyinde yanlış bir şeydir.

Gönderen Wiki :

Temmuz 2004'te, Birleşik Krallık telekom sağlayıcısı BT Grubu, Internet Watch Foundation tarafından potansiyel olarak yasadışı olduğu belirlenen içerik taleplerine 404 hatası veren Cleanfeed içerik engelleme sistemini kurdu. Diğer ISS'ler aynı durumlarda bir HTTP 403 "yasak" hatası döndürür. Tayland ve Tunus'ta sansürü gizlemenin bir yolu olarak sahte 404 hatalarının kullanıldığı bildirildi. 2011 devriminden önce sansürün ağır olduğu Tunus'ta, insanlar sahte 404 hatalarının doğasının farkına vardı ve "görünmez sansürü" temsil eden "Ammar 404" adlı hayali bir karakter yarattı.

Neden böyle bir şeyle cevap vermiyorsun?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

İstek mantıksal olarak başarısız olsa bile Google, her zaman 200'ü Geocoding API'sında durum kodu olarak döndürür: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

REST isteği başarısız olsa bile Facebook başarılı HTTP istekleri için her zaman 200 döndürür: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling

Çok basit, HTTP durum kodları HTTP istekleri içindir. REST API Sizin, durum kodlarınızı tanımlayın.


3
Aslında, REST için HTTP durum kodlarını kullanmak daha da kafa karıştırıcıdır: 1) geliştiricinizin araç kutusunda 4xx görürsünüz ve sunucunun mantıklı bir değer döndürüp döndürmediğini veya isteğinizi hiç işleyemediğini söyleyerek söyleyemezsiniz. ve daha sonra 2) tüm hata / istisna / catch işleyicileriniz hangi sunucunun yanıt olarak döndüğünü kontrol etmelidir (çoğunlukla her servis çağrısında yapmak zorunda kalmazsınız) ve birçok kez 3) aynı yükü alırsınız ( tür) hem başarı hem de hata yolu üzerinde karmaşık / çoğaltılmış koda yol açıyor ... Gerçekten çok kafa karıştırıcı.
szczepanpp

9
Bu yanıt, HTTP protokolünün orijinal anlamını ve mimari bir stil olarak HTTP üzerinden REST'in web hizmeti API'lerini uygulamak için HTTP'yi nasıl amaçladığını karıştırmaktadır . Mimari bir stil olarak REST, titizlikle takip edilecek bir standart değildir, önerilen bir yaklaşımdır. Doğrulama hatası için 200 yanıt kullanmak doğru veya yanlış değildir, ancak isteğinizin başarılı olduğunu ancak yanıtın gövdesinde gizlenen önemli bir ayrıntı olan doğrulama başarısızlığı nedeniyle başarısız olduğunu yanıtlamak istemcilerinizi şaşırtmaktadır. müşterinin anlamak için ayrıştırması gereken anlambilim.
Kevin Hooke

5
@Marcodor, API çağrınız başarısız olursa ancak başarıyı gösteren 200 değerini döndürürseniz, bu nasıl iyi bir fikirdir? API'nızın tüketicileri için belirsiz ve kafa karıştırıcı.
Kevin Hooke

3
Sadece HTTP ve REST hatalarının ayrılması değil, birçok nedenden dolayı düzeltin. REST doğrulaması genellikle daha fazla nüans gerektirir. Örneğin, benzersiz bir dizin ihlali nedeniyle kayıt kabul edildi ancak yinelenen olarak işaretlendi veya reddedildi. Ayrıca tutarlı bir dönüş modeli istiyorsunuz. .NET BadRequest()yönteminin normal dönüş modelinizden farklı olacak kendi dönüş modeli vardır. Ayrıştırma kabusu. @KevinHooke, REST doğrulama hatası için HTTP 200'ü döndürerek, "Mesajınızı aldım, cevap hayır, ve işte nedeni" demeye benzer. HTTP 400'ü döndürmek, "Neden bahsettiğinizi bilmiyorum" diyor.
Neil Laslett

5
"çünkü google bunu yapar, doğru olmalı" argüman bana deli .. google çocuklar uyguladığı bir şey meydan ok tamam. Başarısız bir dinlenme çağrısı için HTTP 200'ü döndürmek, API'nın arayanını karıştırır ve 4xx olması gerekir ve biri vücuda güzel bir JSON / XML içerebilir ... deliliği birlikte durduralım.
Jeryl Cook

43

Veritabanındaki bir kopya bir olmalıdır 409 CONFLICT.

422 UNPROCESSABLE ENTITYDoğrulama hataları için kullanmanızı öneririm .

Burada 4xx kodlarının daha uzun bir açıklamasını yapıyorum .


6

Durum Kodu 304 Değiştirilmedi , yinelenen bir isteğe de kabul edilebilir bir yanıt verir. Bu, If-None-Matchbir varlık etiketi kullanma üstbilgisini işlemeye benzer .

Kanımca, @ Piskvor'un cevabı, algıladığım şeyin orijinal sorunun amacı olduğunu daha açık bir seçenektir, ancak aynı zamanda alakalı bir alternatifim var.

Yinelenen bir talebi hata yerine uyarı veya bildirim olarak ele almak istiyorsanız, 304Değiştirilmedi yanıt durumu kodu Content-Locationve mevcut kaynağı tanımlayan başlık da aynı şekilde geçerli olur. Amaç yalnızca bir kaynağın var olmasını sağlamaksa, yinelenen bir istek bir hata değil bir onay olur. İstek yanlış değil, yalnızca gereksizdir ve istemci varolan kaynağa başvurabilir.

Başka bir deyişle, istek iyidir, ancak kaynak zaten mevcut olduğundan, sunucunun başka işlem gerçekleştirmesi gerekmez.


6
304'ün GET operasyonlarına önbelleklemede yardımcı olması için tasarlandığını anladım.
Sinaesthetic

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.