Genel başarısız bir istek için uygun HTTP durum kodu yanıtı nedir (bir hata değil)?


109

Saklanan kredi kartlarını kullanarak sipariş vermek de dahil olmak üzere bir dizi kullanıcı etkileşimini işleyecek bir RESTful API oluşturuyorum.

Başarılı bir sipariş durumunda 200 OK iade ediyorum ve sipariş talebinin hatalı biçimlendirilmesi veya geçersiz olması durumunda 400 Hatalı İsteği iade ediyorum. Ancak siparişin fiili işlenmesi sırasında bir sorun olursa ne iade etmeliyim?

  1. İstemci POSTS bir kullanıcı kaynağı için sunucuya sipariş. Kullanıcı yoksa, 404 Bulunamadı döndürülür.
  2. Sipariş formatı ve bilgiler doğrulanır. Geçerli değilse, 400 Hatalı İstek döndürülür.
  3. Sipariş işlendi. Sipariş başarılı olursa sipariş için 201 Oluşturuldu iade edilir. Beklenmeyen bir hatayla karşılaşılırsa, 500 Sunucu Hatası döndürülür.

Son adım sorun - sipariş başka bir nedenden ötürü tamamlanmazsa ne iade ederim? Olası senaryolar şunları içerebilir:

  • Ürün tükendi
  • Kullanıcı maksimum sipariş sınırına ulaşıldı
  • Kredi kartı işlemi hatası (yetersiz bakiye vb.)

Bu, 400 veya 500 için uygun gibi görünmüyor. Daha iyi bir kod yoksa, 400 olarak görebildiğim bir şey varsa - istek iş kurallarına göre geçersizdi. Sadece doğru görünmüyor.

Düzenleme: Aynı konuyla ilgili bu mevcut tartışmayı da buldu . Buradaki tüm cevaplar, 400, 409 veya 422 uzantılarının kullanılması arasında bazı tartışmalarla birlikte, bu tür ihlal için durum kodlarının kullanılmasına işaret ediyor gibi görünüyor.


8
Doğrulama hataları için "422 işlenemeyen varlık" ı seviyorum. Ve bunu yukarıdaki örnekleriniz için kullanırsınız, gerçek iş sorunu olan "Ürün tükendi" yanıtına bir mesaj ekleyin ve müşterinin yanıta dayalı olarak programlı olarak farklı kararlar alması gerekiyorsa muhtemelen kendi "kodlarınızı" ekleyin
ev9

422'ye geçmeden önce, WebDAV özelliklerini destekleyip desteklemediğinizi düşünün
Mbithy Mbithy

Yanıtlar:


90

İş kuralları için 400 kullanmalısınız. Sipariş kabul edilmediyse 2xx'i iade etmeyin. HTTP bir uygulama protokolüdür, bunu asla unutmayın. 2xx'i iade ederseniz, vücutta gönderdiğiniz bilgilerden bağımsız olarak müşteri siparişin kabul edildiğini varsayabilir.


Gönderen RESTful Web Hizmetleri Cookbook :

Bazı web hizmetlerinin yaptığı yaygın bir hata, başarıyı yansıtan bir durum kodu döndürmektir (durum kodları 200'den 206'ya ve 300'den 307'ye), ancak bir hata durumunu açıklayan bir mesaj gövdesi içerir. Bunu yapmak, HTTP'yi tanıyan yazılımların hataları algılamasını engeller. Örneğin, bir önbellek bunu başarılı bir yanıt olarak depolar ve istemciler başarılı bir istekte bulunabilse bile sonraki istemcilere sunar.

4xx ve 5xx arasında karar vermeyi size bırakacağım, ancak bir hata durum kodu kullanmalısınız.


1
Bu yaklaşım için diğerine karşı herhangi bir örnek veya referansınız var mı? Hem sizin hem de Widor'un yanıtları, biri bir uygulama protokolü olarak HTTP açısından, diğeri ise kesinlikle aktarım amacına yönelik olduğu için anlamlıdır. Spesifikasyon, onu biraz belirsiz olan "uygulama düzeyinde bir protokol" olarak tanımlar. Bunu araştırırken web'de hem perspektifleri hem de örnekleri gördüm.
Raelshark

bu çok doğru.
Young Hyun Yoo

2
'İş kuralları için 4xx kullanmalısınız' demek mi istiyorsunuz?
Yawar

28

İstemci, hatayı aşmak için isteği değiştirebiliyorsa, bir istemci hatası için 4xx kullanmalısınız. İstemcinin gerçekten çalışamayacağı bir sunucu hatası için 5xx kullanın.

Satılan ürün bir sunucu hatası olur. İstemci, hatayı aşmak için isteği bir şekilde değiştiremez. Başka bir ürüne geçebilirsin ama bu yeni bir talep olmaz mıydı?

Ulaşılan maksimum kullanıcı sipariş sınırı da bir sunucu hatasıdır. İstemcinin bu hatayı çözmek için yapabileceği hiçbir şey yok.

Kredi kartı işleminin başarısızlığı bir müşteri hatası olacaktır. Müşteri, hatayı çözmek için talebi farklı bir ödeme yöntemi veya kredi kartı numarasıyla yeniden gönderebilir.


6
Sipariş sınırına ulaşılırsa, müşterinin kullanıcıyı bu konuda uyarması ve isteğini uygun şekilde değiştirmesine izin vermesi gerekmez mi? Bu bir 4xx hatası gibi görünüyor. Aynı şey satılan ürün için de geçerli. 5xx hataları, bir iş kuralı tarafından izin verilmeyen bir eylem için değil, sistemin bir şekilde bozulmasından kaynaklanan hatalar içindir.
carlin.scott

7
Yukarıdaki yoruma katılıyorum. 5xx hataları, sunucuda sorun olduğunda ortaya çıkar. İş kuralları için 4xx hataları.
Merc

21

Hata türü:

4×× Client Error

Hata kodu:

422 Unprocessable Entity

Sunucu, istek varlığının içerik türünü anlar (bu nedenle bir 415 Desteklenmeyen Ortam Türü durum kodu uygun değildir) ve istek varlığının sözdizimi doğrudur (bu nedenle bir 400 Kötü İstek durum kodu uygun değildir), ancak içerileni işleyemedi Talimatlar.

Ö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.

https://httpstatuses.com/422


16

Bu sorunun eski olduğunu biliyorum ama bugün aynı soruyla geldim. Kullanıcımın kredisi biterse, REST API'm hangi durum kodunu döndürmelidir?

Eğilme eğilimindeyim 402 Payment Required :

Wikipedia'ya göre :

Gelecekte kullanılmak üzere rezerve edilmiştir. Asıl amaç, bu kodun bir tür dijital nakit veya mikro ödeme planının bir parçası olarak kullanılabilmesiydi, ancak bu gerçekleşmedi ve bu kod genellikle kullanılmıyordu. Google Developers API, belirli bir geliştirici günlük istek sınırını aştığında bu durumu kullanır.

Ve gerçekten de yapıyorlar :

PAYMENT_REQUIRED (402)

  • Geliştirici tarafından belirlenen günlük bütçe sınırına ulaşıldı.
  • İstenen işlem, kotanın izin verdiğinden daha fazla kaynak gerektiriyor. İşlemin tamamlanması için ödeme yapılması gerekmektedir.
  • İstenen işlem, kimliği doğrulanmış kullanıcıdan bir tür ödeme gerektiriyor.

Bu en iyi düşünülmüş ve mantıklı cevaptır.
GTodorov

5

Nasıl olur 424 Failed Dependency? Spesifikasyon bunu şu şekilde tanımlar:

İstenen eylem başka bir eyleme bağlı olduğundan ve bu eylem başarısız olduğundan, yöntem kaynak üzerinde gerçekleştirilemedi.

Ama bir de şu tanım var :

Durum kodu 424, WebDAV standardında tanımlanmıştır ve istemcinin yaptığı şeyi değiştirmesi gereken bir durum içindir - sunucu burada herhangi bir sorun yaşamıyor.

Müşteriye, siparişi yaratması ve bakiyeyi düşürmesi gereken dahili eylemleriniz olduğunu ve bu eylemlerden birinin, tamamen geçerli nedenlerle de olsa başarısız olduğunu ve bu nedenle talebin başarısız olduğunu söyleyebilirsiniz.

Görebildiğim kadarıyla, "eylem" oldukça geniş bir terimdir ve yetersiz stok, yetersiz kredi veya ambar partisi gecesi gibi çeşitli durumlarda kullanılabilir.


Başka bir seçenek de şunlar olabilir 422 Unprocessable Entity:

Sunucu, istek varlığının içerik türünü anlar (bu nedenle bir 415 Desteklenmeyen Ortam Türü durum kodu uygun değildir) ve istek varlığının sözdizimi doğrudur (bu nedenle bir 400 Kötü İstek durum kodu uygun değildir), ancak içerileni işleyemedi Talimatlar.

Ö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.

Stokta olmayan veya yetersiz krediniz olduğunda bir ürünü talep etmeye çalışmak, anlamsal düzeyde bir hata olarak kabul edilebilir.

MozDev , bunun istemci tarafında bir hataya işaret ettiğini söylüyor , özellikle: İstemci bu isteği değişiklik yapmadan tekrar etmemelidir.

Loopback 4 , giriş doğrulama başarısız olduğunda 422'yi kullanır .


Muhtemelen, yetersiz stok veya ambar partisi gecesi geçici durumlar olarak kabul edilebilir, bu nedenle talep daha sonra tekrar denenebilir. Bu durum şu şekilde gösterilebilir:503 Service Unavailable

Sunucu, geçici bir aşırı yüklenme veya zamanlanmış bakım nedeniyle şu anda isteği işleyemiyor ve bu durum, bir miktar gecikmeden sonra büyük olasılıkla azalacaktır.

Sunucu, istemcinin isteği yeniden denemeden önce beklemesi için uygun bir süre önermek üzere bir Yeniden Deneme Başlığı alanı gönderebilir.


Bunların hiçbiri bir ödemeyle ilgili değil. Önceki cevaptan 402 ile gidiyorum!
GTodorov

2

400'ün tüm iş senaryoları için kullanılabileceğini sanmıyorum. Temel veri girişi doğrulaması için kullanılabilir. Bunun ötesinde, diğer iş mantığını bu hata koduna sığdırmakta zorlanabiliriz. Bununla ele alınan hata, çoğunlukla geliştiricinin muhtemelen istemcinin kodlaması sırasında karşılaşacağı tasarım zamanı hatalarıdır.

Diyelim ki tüm parametreler doğru ve kullanıcı hesap numarasını talebe geçirdiğimizi varsayalım.

Dolayısıyla istek artık kötü bir istek değildir, sunucu isteği kabul edebilir. Ancak şimdi, hesabın yeterli bakiyesi olmayan mevcut yeni bilgilere dayanarak talebin yerine getirilmesini reddediyor.

Bu senaryolarda uygun hata mesajıyla 403 kullanmamızı öneririm.

Diğer olası hata kodu 409 çakışması olabilir. Ancak bu, kaynağın tutarlı durumda olduğu senaryolarda kullanılır.


0

406 ile gidiyorum Not Acceptable.

İşte 4xx listesi:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585

8
406 durum kodunun adı kendi başına doğru görünse de, her bir durum kodunun yetkili bir metinsel açıklamaya sahip olduğunu bilmeniz gerekir. Durum kodu 406 için açıklama, mevcut durum için uygun değildir . Örneğin, httpstatuses.com/406 adresine bakın .
Zero3

1
@ Zero3 doğru, bu kod, istemciden gönderilen Accept Header'lar ile uç nokta tarafından gönderilen MediaType (lar) arasında bir uyuşmazlık olduğu için yanıt türünün kabul edilemez olduğu anlamına gelir, örneğin application / json vs. text / plain
Gregor
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.