“Sonuç Yok”, RESTful bir cevapta bir hata mı olmalı?


52

Bir örnek tanımlayacağım:
Bir fırıncı dükkanı için bir API yapmaya başladım. API, insanların kendi kataloglarını kullanarak ev yapımı minyatür çikolatalı kurabiye gibi unlu mamuller için arama yapmalarını sağlar api.examplebakery.com/search?q=......

Birisi bunu adında bir ürün aramak için kullanıyor pineapple-banana flavoured cookiesve açıkça bir sonuç bulamıyor.

Bu bir hata olarak mı iade edilmelidir? Arama başarısız oldu, API arandı ve başarıyla çerez bulunamadı. API 404gerçekten bulunmadığından, API döndürülmemelidir .




3
@gnat: Bu bir kopya değil çünkü diğer soru belirli bir kaynakla ilgili, birden fazla kaynağa karşı bir sorgu değil.
Greg Burghardt

7
Benzer şekilde, bir nesne dizisi döndüren bir işleve sahip olduğunuzu varsayalım. Belirli bir kullanım durumuyla eşleşen herhangi bir nesne yoksa, bir istisna yerine işlev mi yoksa boş bir dizi mi döndürürsünüz?
Kevin - Monica

2
@AakashM HTTP-204'ü bir GET isteğine geri döndürmek oldukça sıradışı, bunu hiçbir yerde görmediğimi biliyorum. Bildiğim kadarıyla, HTTP-204 genellikle sunucudaki bir kaynağı değiştirirken cevap olarak kullanılır, örneğin POST / PUT / DELETE istekleri.
Radu Murzea

Yanıtlar:


122

Sonuçlar olduğunda, çıktı bir (JSON, yorumunuza göre) listesidir. Sonucu olmayan sorgular için çıktı tam olarak aynı olmalıdır. Liste basitinde 0 adet öğe vardır.

Yani cevabınız normalde bu ise:

{
    "results": [
        {
            "name": "Pancakes",
            ....
        },
        {
            "name": "French Fries",
            ....
        }
    ]
}

Sonra 0 sonuç içeren bir sorgu için, bu olmalıdır:

{
    "results": []
}

Ayrıca, sonuçların kaç "sayfasının", bu "sayfaların" bağlantılarının vb. Olduğu hakkında meta veri de eklerseniz, o zaman 1 "sayfa" olduğunu söyleyebilirim.

HTTP durumu - sonuçları olduğunda aynı olmalıdır 200 OK.

204 No Contentbir seçenek olarak görünebilir, ancak bunun nedeni aslında "içerik" i (boş liste) döndürmeniz değildir. Boş bir listenin "içerik" olarak sayılmadığını düşünüyorsanız, yazım önerileri sunma yanıtını değiştirirseniz ne olur? Yanıtın özü hala boş bir liste olacak, ama şimdi daha da fazla "içerik" var.

HTTP durum kodları hakkında daha faydalı bilgiler için, jpmc26 cevapları okumaya değer.


9
Bu, boş nesne kalıbı ile aynı düşünce şeklidir . Hatalar ve boş burada hiçbir şey olmadığını söylemenin tek yolu değil. Bazen hiçbir şeyinizi sessizce ifade etmek istersiniz. Bu şekilde müşteriler hiçbir şey için test yapmak zorunda kalmazlar.
candied_orange 28:17

54
İçerik döndürürken, 204'ü iade etmenin uygunsuz olduğunu savunuyorum. Sadece içeriğin bir sonucu yok, bu da hiçbir içeriğin döndürülmemesinden farklı.
TMN

9
@TMN onayladı - 204 "sonuç yok" için uygun değil. Sorgunuz her zaman bir dizi döndürmelidir, sonuçta dizinin içindeki sonuçlar bulunur. Sonuç yoksa, müşteri bunu doğal olarak halleder. Müşteri özel bir metin göstermek isterse ("Sonuç bulunamadı"), o zaman sorun değil. 204 yalnızca doğal olarak sonuç döndürmeyen bir bitiş noktası için döndürülmelidir.
JasonB

1
Eğer ben Recon boş bir dize olarak boş tefrika dönen eğer 204 kullanabilirsiniz
Ewan

15
Bu. Bir RESTful API oluştururken önemli olan şey, aksilik değil API kısmıdır. İyi bir API, müşteriler / tüketiciler için hayatı kolaylaştırır. Boş bir dizi boş değerlerden / istisnalar / durum kodlarından daha kolaydır.
Guran

37

Ne zaman bir HTTP koduna karar verirsen, daima bu soruyu sormalısın:

İsteğe bağlı herhangi bir müşteri yanıtla ne yapabilir / yapacak / yapmalıdır?

  1. Müşteri yanıtı her zaman bir başarısızlık olarak görmeli mi? Ardından, sorunun müşterinin girişi veya sunucunun işlemleri olmasına bağlı olarak 4xx veya 5xx'i istersiniz.
  2. Müşteri bunun yerine başka bir yerde talepte bulunmalı mıdır? O zaman 3xx senin için.
  3. Sunucu, müşterinin istediği şeyi yaptı mı (başarılı oldu)? Bu 2xx.

Her zaman önce cevap kodunuzun hangi aralıkta olacağına karar verin. Bunu hızlı bir şekilde yapmak, seçenek olarak birçok yanıt kodunu ortadan kaldırır ve (belki de daha önemlisi) kodların anlamlarını takip etmeyi çok daha basit hale getirir. Her bir kod kategorisinin neyi temsil ettiği ile ilgili açıklamalar için HTTP kodu belgelerinin başlangıç ​​bölümlerine bakın .

Bu durumda, müşteri geçerli, mevcut bir uç noktadan filtre verilen sonuçların bir listesini istedi ve erişim yetkisi var. Sunucu isteği işleme koymayı ve döndürecek uygun verileri belirlemeyi başardı (öğe yok), böylece istek başarılı oldu. Sadece verdikleri filtrenin tüm sonuçları filtrelemesiyle olur . İstemcinin istediğinin bu olup olmadığını belirlemek sunucuya bağlı değildir, çünkü bu bazı istemciler için beklenen bir sonuç olabilir. Bir şekilde müşteri kodu için bir sorunsa, uygun bir şekilde belirlemek, kontrol etmek ve işlemek müşterinin sorumluluğundadır. Yani bu açıkça 2xx.

Şimdi soru şu, "Hangi 2xx?" Bu, sunucunun nasıl yanıt vereceğini düşündüğünüze bağlıdır.

  • Diğer bazı cevapların tanımladığı gibi boş bir listenin temsilini geri gönderir misiniz ? Öyleyse, 200 istiyorsun. 200, sunucunun hiçbir sorun yaşamadığı ve müşterinin tüketmesi için sonuçları temsil ettiği anlamına gelir. Bu muhtemelen, sonuçları olup olmadığına cevabını çözümleyebilen ve sonra boş bir listenin kendi başlarına nasıl idare edilebileceğini çözebilen, tüketicilerinize cevap vermenin en uygun yoludur.
  • 204 burada anlamsal olarak yanlış değildir, ancak herhangi bir mesajlaşma organıyla cevap vermemelisiniz . Bu, tüm müşteri kodlarının açıkça farklı HTTP kodlarını (veya en azından bir mesaj gövdesinin olmaması için) kontrol etmesi ve ayrı ayrı işlemesi gerektiği anlamına gelir. Uygunsuz davranıyor ve kötü niyetli müşterilere yol açması daha olası.

Diğerleri hiçbiri için geçerli değildir:

  • 201 söz konusu değil. Kalıcı kaynaklar oluşturmadınız ve bir konumu oluşturulan kaynaklara geri döndürmediniz.
  • 202 söz konusu değil. İstek yapıldı; arka planda işlemiyor.
  • 203, yanıtın yetkili sunucu ile istemci arasında değiştirildiği anlamına gelir. Sizin RESTful arayüzü olan bu burada geçerli değildir, bu yüzden yetkili sunucusu.
  • 205 mantıklı değil. Herhangi bir şeyi silmek veya yenilemek için müşteriye ihtiyacınız yok.
  • 206, çok sayıda yanıt üzerinden büyük bir kaynağın geri gönderilmesi için tasarlanmış gibi görünmektedir. Ayrıca, müşterinin başlıklardaki içeriğin bir kısmını istemesini de gerektirir (bu nedenle sorgu dizeleriyle sayfalama uygun değildir). Burada geçerli değil.

Bu yüzden ya 200 ya da 204 olmalı ve 200'ün daha basit, daha sağlam bir müşteri koduna yol açması daha muhtemeldir (özellikle boş bir liste içeren tutarlı bir cevap yapısı kullanıyorsanız).


5
Hakemin görüşüyle ​​ilgilenirim. Bunların hiçbirinin tartışmalı olduğunu sanmıyorum.
jpmc26

2
Müşterilerin açıkça 204'ü kontrol etmesi gerektiğini sanmıyorum. Tek ihtiyaçları olan, boş yanıt nesnesini idare edebilmek. "Gövde ayrıştırma" bölümünü atlayarak 204'ü işlemek HTTP çerçevesinin işidir. İçerik Uzunluğu 4 ile 200 ve vücut boşluğu aynıdır.
Ajan_L

1
@Agent_L Sunucu normal yanıtla tutarlı olmayan bir yapıya yanıt verirse ( nullnormalde listenin bulunduğu yere koyma gibi ), 200'le bile tutarlılık avantajlarından yararlanamayacağınız konusunda haklısınız. normal yapıyla tutarlı olan ve sonuç listesinin normalde uygulanacağı boş bir liste var. 204, bu kadar tutarlı bir cevap alma fırsatını ortadan kaldırır. Ayrıca, kolaylık işlevine sahip HTTP istemci kitaplıklarında bile, sık sık (tipik olarak?) JSON'u ayrıştırmak için açık bir çağrı yapmanız gerekir.
jpmc26

@Agent_L Özellikle listelerde, arayanlar genellikle kodlarının boş bir liste üzerinde normal şekilde çalışmasına izin verebilir (örneğin üzerine döngü yaparak), başka bir temsil türünü idare etmek için belirli bir tür açık kontrole ihtiyaç duyarlar.
jpmc26

16

Hayır. 404'ü kullanarak 'sorgunuz işlendi ancak eşleşme olmadı' belirtmek için kullanışsız:

  • istisna işlemeye dayalı koşullu akış (yani, istemcide performans göstermeyen ve garip olabilen bir istisna oluşturmak ve işlemek için istisnai olmayan bir sonuç zorlamak)

  • 'gerçek' sayfa arasında belirsizlik bulunamadı, bitiş noktasını yanlış yazdınız

Hatırlanması gereken şey, her zaman mesajın seriyi kaldırmak için bir müşteri olduğu ve bu müşterinin ne döndürdüğü önemlidir; serileştirme değil.

İstemci null değerine dönerse, null seri hale getirmesini kullanın. İstemcinin boş bir dizi döndürmesi gerekiyorsa, [] kullanın, istemci bir hata atarsa ​​500 kullanın ve hata iletisini iletin


2
Sunucu neden müşterinin bilgilerle ne yaptığını önemsemelidir? (PS: Cevabınızı düşüren kişi ben değilim).
Radu Murzea

Bu bağlamda 'istemci', hizmeti istemci uygulamaya uygulayan istemci cihazda çalışan koddur. Hizmet yöntemlerini ortaya çıkarabilmeli ve sonuçları hizmet tarafından amaçlandığı şekilde iade edebilmelidir. İletişimin çalışabilmesi için bir müşteri-sunucu çiftine ihtiyacınız var
Ewan

3
Elbette, müşteri hataları için 5xx kullanmayın . Bu durumda 4xx tercih edin.
Kevin,

1
Bununla birlikte, bu örneklerin çoğunda "istemci" değil, "sunucu" olmamalıdır? İsteği işleyen ve bir yanıt sunan sunucu, istemci yalnızca yanıtı işliyor mu? Bu durumda bir 5xx kodu TAMAM olacaktır, çünkü bir sunucu hatasıdır, istemci hatası değil mi?
MrWhite

2
tüm hata kodlarıyla ilgili sorun http içinde anlam ifade etmeleridir. 500, hizmetiniz bir istisna atarken uygun olan tek koddur
Ewan

9

@ Ewan'ın çok iyi cevabının ötesinde:

Sorgu, sonuç kümesini döndüren türdeyse, boş küme mantıksal olarak bir küme veya başka bir küme kadar uygundur. Genel olarak @ Ewan'ın belirttiği nedenlerden ötürü, boş kümeyi bir hataya dönüştürmenin iyi olacağından daha fazla zararı vardır ve sadece gereksizdir.

Sorgu, aranan ve belirli bir tekil ifadeyi döndüren türdeyse (bulunması bekleniyor, örneğin kimliğe göre tam eşleşme), bulunamaması mantıksal olarak uygun bir cevaptır.


Evet, tam olarak Ewan'ın cevabını düşündüm.
Walfrat

5

Kodun, hiçbir veri döndürülmediğinde özel bir işlem yapması gerektiğini varsayıyorsunuz, ancak durum böyle olmayabilir. Kod basitçe bir ürün sayısı arıyor olabilir veya sonuçları bir listeye veya herhangi bir şeye ekliyor olabilirsiniz. Bir kullanıcıya yalnızca "hata" veriyor olmanız gerekir, aslında bir hata varsa.


3
"Gerçekten bir hata varsa bir kullanıcıya yalnızca" hata "veriyor olmalısınız." - bu. Bir "arama" yaparken belirlenen boş sonuçlar normalde "hata" değildir. Bununla birlikte, eğer veritabanı bağlantısı başarısız olduysa, aramanın gerçekte gerçekleştirilemeyeceği anlamına gelirse, o zaman boş bir sonuç seti (ve hata yok) aksi takdirde belirsiz olacaktır. Bu durumda bir çeşit hata durumu uygun olabilir (API'nin nasıl tanımlandığına bağlı olarak belki boş bir sonuçla birlikte).
MrWhite

0

Bir API kullandığımda, bir istemci olarak "hata" durumlarından farklı "başarılı" durumları ele almalıyım; Orada başka şansım yok. Bu nedenle, müşterinin farklı davranmak istediği durumlarda bir hata ve müşterinin de aynı şekilde davranmak istediği durumlarda başarılı olmalısınız .

Teorik olarak herhangi bir sayıda sonuç, sıfır, bir, iki yüz ve daha fazla sonuç verebilecek bir sorgu yaparsam, API tüm sonuçların tam listesini verdiğinde "başarı" yı döndürmelisiniz. Muhtemelen çok fazla sonucun olduğu durumlarda, aşırı büyüklükten kaçınmak için kısmi bir sonuç listesi döndürdünüz ve diğer sonuçları nasıl elde edeceğime karar verdiler. Çünkü bir müşteri olarak, daha fazla sonuç durumunda olduğu gibi sıfır sonuç vakasını ele almak istiyorum. Ona farklı davranabilirim, ama buna zorlanmak istemiyorum.

Bir değer aramam durumunda farklıdır. Tam olarak bir sonuç bekliyorum, aradığım değeri. Ve yapmak istediğim şeyi anlamlı bir şekilde sürdürmek için bu sonuca ihtiyacım var. Burada hiçbir değerin olmadığı durumda 404 statüsünün döndürülmesi daha kabul edilebilirdir, çünkü bu olayı farklı şekilde ele almam gerekiyor.

Özet: Müşteri, sıfırdan büyük sayılara kadar herhangi bir sayıda sonuç beklerse, sonuç sıfırsa bile, tüm sonuçlar iletilirse "başarılı" ifadesini döndürün. İstemci tam olarak bir sonuç beklerse, sonuç bulunursa başarı ve sonuç bulunmazsa hata döndürülür.

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.