REST API hata dönüşü iyi uygulamaları [kapalı]


623

Bir REST API hata döndürmek söz konusu olduğunda iyi uygulamalar hakkında rehberlik arıyorum. Ben şu anda herhangi bir yön alabilir böylece yeni bir API üzerinde çalışıyorum. İçerik türüm şu anda XML, ancak gelecekte JSON'u desteklemeyi planlıyorum.

Şimdi, örneğin bir istemci yeni bir kaynak eklemeye çalışır ancak depolama kotasını aşmış gibi bazı hata durumları ekliyorum. HTTP durum kodlarıyla (kimlik doğrulama için 401, yetkilendirme için 403 ve düz hatalı istek URI'ları için 404) belirli hata durumlarını zaten ele alıyorum. Mübarek HTTP hata kodlarına baktım ama 400-417 aralığının hiçbiri uygulamaya özgü hataları bildirmek için doğru görünmüyor. Bu yüzden ilk başta 200 OK ve belirli bir XML yükü ile uygulama hatamı döndürmek cazip geldi (yani. Bize daha fazla ödeme yapın ve ihtiyacınız olan depolamayı alacaksınız!) Ama düşünmeyi bıraktım ve sabunlu görünüyor (/ / korku içinde omuz silkme). Yanı sıra bazı http durum kodu tahrik ve diğer içerik tahrik gibi hata yanıtları ayrı durumlarda bölünmüş gibi geliyor.

Peki endüstri önerileri nedir? İyi uygulamalar (lütfen nedenini açıklayın!) Ve ayrıca bir müşteri pov'sinden, REST API'sinde ne tür bir hata işleme, istemci kodu için hayatı kolaylaştırır?


7
Sadece açıklığa kavuşturmak için: Hangi HTTP durum kodunun döndürüleceği ile pek ilgilenmiyorum, ancak yük hatalarını HTTP durum kodlarıyla birleştirmek için iyi bir REST uygulaması mı yoksa yalnızca yüke güvenmek mi daha iyi.
Remus Rusanu

3
REST API Tasarım El Kitabı bu konuyu oldukça iyi bir şekilde ele almaktadır.
Remus Rusanu

12
Soru görüş istemez, rehberlik / öneriler için geçerlidir ve yeniden açılmalı ve referans olarak kullanılmalıdır. 2009'da oluşturulan soru, 2016'da kapanacak nokta
neydi 400+ oyu var

4
Çoğu söz etmedi, ancak HTTP hata kodlarını kullanmak bir sorunun ana nedeni ile ilgili sorunlara yol açabilir. HTTP, aktarım protokolüdür ve 404, URLon aktarım düzeyiyle ilgili bir sorun olduğunu belirtmelidir (örn. Yanlış yol). Uygulama kimliğine göre bir veri kümesi bulamazsa, bu bir uygulama düzeyi hatasıdır (taşıma düzeyi hatası değildir) ve dinlendirici http durum kodu kullanıcıları tarafından önerildiği gibi bir 404 yanlış bir sonuca yol açabilir. Genel olarak, durum kodlarını kullanmada taşıma ve uygulama katmanının karışmasını sevmiyorum.
SCI

Yanıtlar:


220

Bu yüzden ilk başta 200 OK ve belirli bir XML yükü ile uygulama hatamı döndürmek cazip geldi (yani. Bize daha fazla ödeme yapın ve ihtiyacınız olan depolamayı alacaksınız!) Ama düşünmeyi bıraktım ve sabunlu görünüyor (/ / korku içinde omuz silkme).

Gerçekten isteği ile yanlış bir şey olmadığı sürece 200 dönmek olmaz. Gönderen RFC2616 , 200 araç "isteği başarılı oldu."

Müşterinin depolama kotası aşılmışsa (herhangi bir nedenle), bir 403 (Yasak) döndürürdüm:

Sunucu isteği anladı, ancak yerine getirmeyi reddediyor. Yetkilendirme yardımcı olmaz ve istek tekrarlanmamalıdır. İstek yöntemi HEAD değilse ve sunucu, isteğin neden yerine getirilmediğini halka duyurmak istiyorsa, kuruluştaki ret nedenini açıklamalıdır. Sunucu bu bilgileri istemcinin kullanımına sunmak istemiyorsa, bunun yerine 404 (Bulunamadı) durum kodu kullanılabilir.

Bu, istemciye isteğin iyi olduğunu, ancak başarısız olduğunu (200'ün yapmadığı bir şey) bildirir. Bu aynı zamanda size yanıt organındaki sorunu (ve çözümünü) açıklama fırsatı verir.

Aklınızda başka hangi özel hata durumları vardı?


6
Ayrıntılı hata mesajımı gövdeye eklemem gerekir mi, yani. XML kodu / dize çifti? Müşteriler bununla en iyi nasıl başa çıkıyor? Örneğin, C # WebRequest tabanlı istemcilerin "Kötü İstek" veya "Yasak" atacağını ve yanıt gövdesini vermeyeceğini biliyorum.
Remus Rusanu

18
403 "gövdesi" gövdesi hatanın ayrıntılarını içermelidir. Bir müşterinin bilgileri kullanmaya hazır olup olmadığı başka bir hikaye. Bu biçimin diğer tüm yükler (ör. XML, JSON) biçimiyle aynı olması en mantıklıdır.
Zengin Apodaca

1
... ve ayrıntılar 403'te iade edilmezse, bunun yerine 404 "kullanılabilir" (benim için en iyi seçenek gibi görünmüyor).
Rich Apodaca

6
404 seçeneği, bir 403'ün yetkisiz kullanıcıların bilmesini istemediğiniz uygulama hakkındaki ayrıntıları açıklayabilmesidir - örneğin, yönetici olmayan bir kullanıcı yalnızca yönetici URL'sine ulaşırsa, o kullanıcıyı istemeyebilirsiniz. yöneticiler, vb. için geçerli bir URL olduğunu bilmek. Bu durumda, 403 tamamen uygundur.
Greg Campbell

16
Bunun oldukça yararsız bir cevap olduğunu hissediyorum. Durumların tek başına kullanılması gerekip gerekmediği veya hata bilgilerinin yükte veya her ikisinde vb. İade edilmesi gerekip gerekmediği konusunda daha önemli bir husus olduğunu düşünürdüm. Ve sonra bilgi nasıl yüke eklenmelidir. Kullanılan belirli durum, sorunun yalnızca belirli bir yönüne odaklanmaktır.
Manachi

584

API'niz için doğru HTTP hata kodunu seçmek için harika bir kaynak: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

Makaleden bir alıntı:

Nereden başlamalı:

resim açıklamasını buraya girin

2XX / 3XX:

resim açıklamasını buraya girin

4XX:

resim açıklamasını buraya girin

5XX:

resim açıklamasını buraya girin


1
422 Özellikle bir WebDAV uzantısıdır. Bence burada olmamalı.
Mario

@Mario Ruby on Rails API'larında burada belirtilen koşullara yanıt olarak 422'ler döndürmek deyimseldir. Bu yaklaşımı takip eden çok iyi. 422 kullanımlarının yerini ne alırsınız?
Kelsey Hannan

düzenli eski 400
Andbdrew

Teşekkür ederim. "İnternetten öfkeyle ayrılıyor musunuz?"
RoutesMaps.com


87

Ana seçim, HTTP durum kodunu REST API'nizin bir parçası olarak ele almak isteyip istemediğinizdir.

Her iki yol da iyi çalışıyor. Kesinlikle konuşmak gerekirse, REST'in fikirlerinden birinin HTTP Durum kodunu API'nizin bir parçası olarak kullanmanız gerektiğine katılıyorum (başarılı bir işlem için 200 veya 201 ve çeşitli hata durumlarına bağlı olarak 4xx veya 5xx döndürün). , REST polisi yok. Ne istersen yapabilirsin. Çok daha berbat olmayan REST olmayan API'lerin "RESTful" olarak adlandırıldığını gördüm.

Bu noktada (Ağustos 2015) HTTP Durum kodunu API'nızın bir parçası olarak kullanmanızı öneririm. Çerçeveleri kullanırken dönüş kodunu görmek geçmişte olduğundan çok daha kolay. Özellikle, 200 olmayan geri dönüş vakasını ve 200 olmayan yanıtların gövdesini geçmişte olduğundan daha kolaydır.

HTTP Durum kodu, API'nizin bir parçasıdır

  1. Hata koşullarınıza uyan 4xx kodlarını dikkatlice seçmeniz gerekecektir. Yük olarak alt kod ve açıklayıcı bir yorum içeren bir rest, xml veya düz metin mesajı ekleyebilirsiniz.

  2. İstemcilerin HTTP düzeyindeki durum koduna erişmelerini sağlayan bir yazılım çerçevesi kullanmaları gerekir. Genellikle yapılabilir, her zaman kolay değildir.

  3. İstemciler, bir iletişim hatasını gösteren HTTP durum kodları ile uygulama düzeyindeki bir sorunu belirten kendi durum kodlarınızı birbirinden ayırmak zorunda kalacaklardır.

HTTP Durum kodu API'nizin bir parçası DEĞİLDİR

  1. Uygulamanız isteği alıp yanıt verdiğinde HTTP durum kodu her zaman 200 olur (hem başarı hem de hata vakaları)

  2. TÜM yanıtlarınız "zarf" veya "başlık" bilgilerini içermelidir. Genellikle şöyle bir şey:

    zarf_ver: 1.0
    status: # istediğiniz kodları kullanın. Başarı için bir kod ayırın.
    msg: "ok" # Kodu yansıtan bir insan dizesi. Hata ayıklama için kullanışlıdır.
    data: ... # Varsa yanıtın verileri.
  3. Yanıt durumu her zaman aynı yerde olduğundan (alt kod gerekmez), kodlarda sınırlama olmadığından, HTTP düzeyi durum kodunu getirmeye gerek olmadığından, bu yöntem istemciler için daha kolay olabilir.

İşte benzer bir fikri olan bir yazı: http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

Ana konular:

  1. Daha sonra gerekirse API'nin anlambilimini değiştirmek için sürüm numaralarını eklediğinizden emin olun.

  2. Belge ...


8
Ty. Seçenek 2 rağmen dinlenme kıyafetleri SOAP gibi görünüyor ...
Remus Rusanu

138
Hayır, her şeyi 200 ile tünellemek hiç de rahat değil. Aracıların, herhangi bir önbellekleme biçimini öldürecek bir işlemin sonucunu anlamasını önler, işlemin anlamını gizler ve bir hatayı işlemek için mesajın içeriğini anlamayı ve bağımsız mesajlar kısıtlamasını ihlal etmeyi gerektirir.
SerialSeb

13
200 ile hata ayrıntılarını döndürmek RESTful olmayabilir, ancak yine de bu yararlı bir cevaptır ("Her iki yol da dinlendirici" sözünü görmezden gelirseniz) ... Daha büyük nokta, RESTful API'nin OP.
MB.

3
HTTP protokolü ile ne istersen yapabileceğine dair genel bir anlayış var gibi görünüyor ve hala "RESTy", bu yanlış. Protokolü yazdıklarınız için kullanın, bu REST'in temel fikirlerinden biridir. Bu nedenle durum kodu protokolünüzün bir parçası olmalıdır .
Ariel M.

Durum kodlarının amacı, çeşitli programlama dilleri, çerçeveleri ve yaklaşımları arasında ortak bir anlayış dili sağlamaktır. Durum kodu anlamları evrensel olana yakındır: API tüketicilerinizin öğrenmesi gereken özel sözdizimi yoluyla doğası gereği daha fazla karmaşıklık kazandıran özel gövdeniz değil.
Kelsey Hannan

40

HTTP / 1.1 RFC'lerde tanımlananlardan daha fazla durum kodu olduğunu unutmayın, IANA kayıt defteri http://www.iana.org/assignments/http-status-codes adresindedir . Bahsettiğiniz durumda 507 durum kodu doğru geliyor.


3
Hmm, bir bakışta "507 Yetersiz Depolama" uygun gibi görünse de, (oldukça spesifik) bir WebDAV uzantısı olarak tasarlandığından ve genel bir "hey alanınız bitmiş" olduğundan dolayı kullanmaktan keyif alıyorum. istisna. Yine de, sanırım kullanabilirsiniz.
Max

1
Hayır, WebDAV'a özel değil. HTTP durum kodları için bir kayıt olmasının bir nedeni vardır.
Julian Reschke

26
507Bu amaç için katılmıyorum . Benim yorumum 507, sunucunun boş olduğu değil, hesabın boş olduğu değil.
Patrick

12
Patrick ile hemfikirim. 5xxhatalar, sunucuyla ilgili hatalar içindir.
Sean

10
418: "Ben bir çaydanlıkım", depolama alanının büyük olmaktan ziyade çok az (bir çaydanlık gibi) olduğunu ve bu nedenle de boş alan olmadığını ima ediyor.
Steve Konves

22

Diğerlerinin işaret ettiği gibi, bir hata kodunda bir yanıt varlığına sahip olmak mükemmel bir şekilde izin verilir.

5xx hatalarının sunucu tarafı olduğunu unutmayın; diğer bir deyişle, istemci isteği geçmek için isteğine hiçbir şey değiştiremez. İstemcinin kotası aşılırsa, bu kesinlikle bir sunucu hatası değildir, bu nedenle 5xx'den kaçınılmalıdır.


Kabul etmem. Kota Aşıldı, bir sunucu hatası (5xx) olurdu çünkü: Müşterinin isteği geçerli ve kota altında 400'lü dizileri hariç tutan başarılı olurdu.
mikek3332002

4
Ancak sunucu yanlış bir şey yapmadı.
Charlie Schliesser

19

İki tür hata vardır. Uygulama hataları ve HTTP hataları. HTTP hataları, AJAX işleyicinize işlerin iyi gittiğini ve başka bir şey için kullanılmaması gerektiğini bildirmek içindir.

5xx Server hatası

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates (RFC 2295 )
507 Insufficient Storage (WebDAV) (RFC 4918 )
509 Bandwidth Limit Exceeded (Apache bw/limited extension)
510 Not Extended (RFC 2774 )

2xx Başarı

200 OK
201 Created
202 Accepted
203 Non-Authoritative Information (since HTTP/1.1)
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status (WebDAV)

Ancak, uygulama hatalarınızı nasıl tasarladığınız gerçekten size kalmış. Örneğin Yığın Taşması response, datave messageözellikleri olan bir nesne gönderir . İnandığım yanıt , işlemin başarılı olup olmadığını (genellikle yazma işlemleri için) içeriyor trueveya falsebelirtiyor. Veri (genellikle okuma işlemleri için) yükünü içerir ve mesaj (örneğin, hata mesajları gibi herhangi bir ek meta ya da yararlı mesajları içerir responseolan false).


2
400, istemci uygulamasındaki bir sorunu belirtmek için de yararlıdır.
dolmen

19

Bunun partiye son derece geç olduğunu biliyorum, ancak şimdi 2013 yılında, yaygın dağıtılmış (RESTful) bir tarzda hata işlemeyi kapsayan birkaç medya türümüz var. Bkz. "Vnd.error", application / vnd.error + json ( https://github.com/blongden/vnd.error ) ve "HTTP API'ları için Sorun Ayrıntıları", application / problem + json ( https: // tools). ietf.org/html/draft-nottingham-http-problem-05 ).


2
Bağlantılar için teşekkürler. taslak-nottingham-http-sorunu artık önerilen bir standarttır: datatracker.ietf.org/doc/rfc7807
seanf

9

Kabul. REST'in temel felsefesi web altyapısını kullanmaktır. HTTP Durum kodları, tarafların HTTP yükünü artırmadan birbirleriyle iletişim kurmalarını sağlayan mesajlaşma çerçevesidir. Yanıt durumunu zaten ileten evrensel kodlar oluşturulmuşlardır ve bu nedenle, gerçekten RESTful olmak için, uygulamaların yanıt durumunu iletmek için bu çerçeveyi kullanmaları gerekir.

HTTP 200 zarfında bir hata yanıtı göndermek yanıltıcıdır ve istemciyi (api tüketicisi) büyük olasılıkla standart olmayan veya tescilli bir şekilde iletiyi ayrıştırmaya zorlar. Bu da verimli değildir; müşterilerinizi "gerçek" yanıt durumunu anlamak için her seferinde HTTP yükünü ayrıştırmaya zorlayacaksınız. Bu işlemeyi artırır, gecikme ekler ve istemcinin hata yapması için bir ortam oluşturur.


3
Başarılı bir yanıtınız veya başarısızlık yanıtınız olsun, büyük olasılıkla yanıtı ayrıştıracaksınız. Bir hata ise, hata mesajını almak için ayrıştırmak istersiniz. Hata yanıtları genellikle küçüktür ve ayrıştırılması hızlıdır. Hata yanıtlarını ayrıştırmaktan kaçınmak için optimize etmeye çalışmaktan endişe etmememiz gerektiğini düşünmüyorum. Hata yanıtını ayrıştırmadan atabilir misiniz? Bence yanlış.
AgilePro

3
200 Tamam alırsanız, iş kurallarınıza bağlı olarak ayrıştırmamayı da seçebilirsiniz. Mesele, onu her zaman ayrıştırıp ayırmamak değil. Mesele niyettir - 200 OK'nin amacı nedir? 200 Tamam ile sarılmış hata mesajları göndererek niyetinize zarar veriyorsunuz.
Kingz

1
"200 iyi niyet nedir?" - taşıma katmanının başarısını gösterir. İstek başarıyla alındı ​​ve cevaplandı, HTTP ile hiçbir ilgisi olmayan sadece uygulamaya özgü bir sorun vardı. +++ Diğer taraftan: REST dünyasına 404 göndermek, bir şeyin bulunmadığı, URL'nin yanlış olduğu veya işlenecek kaynak olduğu veya başka bir şey bulunmadığı anlamına gelir. Mesajı ayrıştırmadan yapamazsınız. IMHO REST sadece katmanları karıştırıyor.
maaartinus

Konflasyon normdur. Akıl yürütme çizginize uygun olan bir sözdizimi sağlar ve iş katmanına odaklanmanızı sağlar. Daha sonra ulaştırma durumu kabul edildi - ilk etapta amaç buydu - REST HTTP ile aynı anda icat edilmedi / önerilmedi - daha sonra geldi ve mevcut altyapıyı DEVLETLERİ ve DEĞİŞİKLİKLERİNİ temsil etmek için kullanmaya karar verdi.
Kingz


5

Lütfen protokol semantiğine sadık kalın. Başarılı yanıtlar için 2xx ve hata yanıtları için 4xx, 5xx kullanın - işinizdeki istisnalar veya diğerleri. Protokolde amaçlanan kullanım durumunda herhangi bir yanıt için 2xx kullanmış olsaydı, ilk etapta başka durum kodları olmazdı.


3

Uygulama hataları için 5xx hatalarını da unutmayın.

Bu durumda ne hakkında 409 (Çatışma)? Bu, kullanıcının depolanan kaynakları silerek sorunu çözebileceğini varsayar.

Aksi takdirde 507 (tamamen standart değil) de işe yarayabilir. Genel olarak hatalar için 200 kullanmazsanız 200 kullanmazdım.


-2

İstemci kotası aşılırsa bu bir sunucu hatasıdır, bu durumda 5xx kullanmaktan kaçının.


3
Neden sunucu hataları için 5xx serisi hataları önlemek?
mikek3332002

7
'istemci kotası aşıldı' sunucu hatası imho değil, istemci kısıtlaması ve 4xx altında olması gerekiyor.
MyGGaN
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.