it-swarm.com.de

Wann wird der HTTP-Statuscode 404 in einer API verwendet?

Ich arbeite an einem Projekt und nachdem ich mehr als eine Stunde lang mit Leuten bei der Arbeit gestritten habe. Ich beschloss zu wissen, was die Leute beim Stapeltausch sagen könnten.

Wir schreiben eine API für ein System. Es gibt eine Abfrage, die einen Organisationsbaum oder einen Zielbaum zurückgeben soll.

Der Organisationsbaum ist die Organisation, in der der Benutzer anwesend ist. Mit anderen Worten, dieser Baum sollte immer vorhanden sein. In der Organisation sollte immer ein Zielbaum vorhanden sein. (Hier begann das Argument). Falls der Baum nicht vorhanden ist, hat mein Mitarbeiter entschieden, dass es richtig ist, die Antwort mit dem Statuscode 200 zu beantworten. Dann hat er mich gebeten, meinen Code zu korrigieren, da die Anwendung auseinanderfällt, wenn kein Baum vorhanden ist.

Ich werde versuchen, Flammen und Wut zu schonen.

Ich habe vorgeschlagen, einen 404-Fehler auszulösen, wenn kein Baum vorhanden ist. Es würde mich zumindest wissen lassen, dass etwas nicht stimmt. Bei Verwendung von 200 muss ich meiner Antwort im Erfolgsrückruf eine spezielle Prüfung hinzufügen, um Fehler zu behandeln. Ich erwarte, ein Objekt zu erhalten, aber möglicherweise erhalte ich tatsächlich eine leere Antwort, da nichts gefunden wird. Es klingt völlig fair, die Antwort als 404 zu markieren. Dann begann der Krieg und ich bekam die Nachricht, dass ich das HTTP-Statuscode-Schema nicht verstanden habe. Also bin ich hier und frage, was in diesem Fall mit 404 los ist? Ich habe sogar das Argument "Es hat nichts gefunden , also ist es richtig, 200 zurückzugeben". Ich glaube, dass es falsch ist, da der Baum immer vorhanden sein sollte. Wenn wir nichts gefunden haben und etwas erwarten, sollte es ein 404 sein.

Mehr Info,

Ich habe vergessen, die abgerufenen URLs hinzuzufügen.

Organisationen

/OrgTree/Get

Tore

/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...

Mein Fehler, beide Parameter sind erforderlich. Wenn ein versionDate angegeben wird, das auf ein Datum analysiert werden kann, wird die geschlossene Revision zurückgegeben. Wenn Sie etwas in der Vergangenheit eingegeben haben, wird die erste Revision zurückgegeben. Wenn nach ID eine ID vorhanden ist, die nicht vorhanden ist, wird vermutlich eine leere Antwort mit 200 zurückgegeben.

Extra

Ich glaube auch, dass die beste Antwort auf das Problem darin besteht, beim Erstellen von Organisationen Standardobjekte zu erstellen. Kein Baum sollte kein gültiger Fall sein und als undefiniertes Verhalten angesehen werden. Ohne beide Bäume kann ein Konto nicht verwendet werden. Aus diesem Grund sollten sie immer anwesend sein.

auch ich habe dies verlinkt (eine ähnliche, aber ich kann sie nicht finden)

http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png

62

Im Zweifelsfall siehe Dokumentation . Wenn Sie die W3C-Definitionen für HTTP-Statuscodes überprüfen, erhalten Sie Folgendes:

200 OK - Die Anforderung ist erfolgreich. Die mit der Antwort zurückgegebenen Informationen hängen von der in der Anforderung verwendeten Methode ab.

404 Nicht gefunden - Der Server hat nichts gefunden, das mit dem Request-URI übereinstimmt.

Im Kontext Ihrer API hängt es sehr davon ab, wie Abfragen erstellt und wie Objekte abgerufen werden. Aber meine Interpretation war immer so:

  • Wenn ich nach einem bestimmten Objekt frage und es existiert, geben Sie 200 Code zurück. Wenn es nicht existiert, geben Sie den korrekten 404 Code zurück.
  • Wenn ich jedoch nach einer Reihe von Objekten frage, die einer Abfrage entsprechen, ist eine Nullmenge eine gültige Antwort, und ich möchte, dass diese mit einem 200 - Code zurückgegeben wird. Der Grund dafür ist, dass die Abfrage gültig war, erfolgreich war und nichts zurückgab.

In diesem Fall sind Sie also korrekt , der Dienst sucht nicht für "eine bestimmte Sache" ist es , eine bestimmte Sache anzufordern , wenn diese Sache nicht gefunden wird, sagen Sie das klar.

Ich denke, Wikipedia bringt es am besten auf den Punkt:

200 OK - ... Die tatsächliche Antwort hängt von der verwendeten Anforderungsmethode ab. In einer GET-Anforderung enthält die Antwort eine Entität, die der angeforderten Ressource entspricht.

404 Nicht gefunden - Die angeforderte Ressource wurde nicht gefunden, ist aber möglicherweise in Zukunft wieder verfügbar. Nachträgliche Anfragen des Kunden sind zulässig.

Scheint mir ziemlich klar zu sein.

In Bezug auf die Beispielanfragen

/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...

Für das Format, sagten Sie, geben Sie immer die nächstgelegene Revision zu diesem Datum zurück. Es wird niemals kein Objekt zurückgeben, daher sollte es immer 200 OK Zurückgeben. Selbst wenn dies in der Lage wäre, einen Datumsbereich anzunehmen, und die Logik darin bestand, alle Objekte innerhalb dieses Zeitrahmens zurückzugeben, die 200 OK - 0 Ergebnisse zurückgeben, ist in Ordnung, da dies die Anforderung war - die Menge von Dingen, die diese Kriterien erfüllten.

Letzteres ist jedoch anders, da Sie nach einem spezifischen Objekt fragen, das vermutlich eindeutig ist und diese Identität aufweist. Die Rückgabe von 200 OK Ist in diesem Fall falsch, da die angeforderte Ressource nicht vorhanden ist und nicht gefunden wird .

Bezüglich der Auswahl von Statuscodes

  • 2xx Codes Sagen Sie einem UA, dass es hat das Richtige getan, die Anfrage hat funktioniert. Es kann dies auch in Zukunft tun.
  • 3xx-Codes Sagen Sie einem UA, was Sie gefragt haben, was wahrscheinlich früher funktioniert hat, aber das Ding ist jetzt woanders. In Zukunft könnte die UA erwägen, nur zur Weiterleitung zu gehen.
  • 4xx-Codes Sagen Sie einem UA es hat etwas falsch gemacht, die von ihm erstellte Anfrage ist nicht korrekt und sollte es nicht versuchen es wieder, ohne zumindest einige Modifikationen.
  • 5xx Codes Sagen Sie einem UA der Server ist irgendwie kaputt. Aber hey, diese Abfrage könnte in Zukunft funktionieren, es gibt also keinen Grund, es nicht noch einmal zu versuchen. (mit Ausnahme von 501, bei dem es sich eher um eine 400-Ausgabe handelt).

Sie haben in einem Kommentar einen 5xx-Code verwendet, aber Ihr System funktioniert. Es wurde eine Abfrage gestellt, die nicht funktioniert und die der UA mitgeteilt werden muss. Egal wie Sie es schneiden, dies ist 4xx Territorium.

Stellen Sie sich einen Außerirdischen vor, der unser Sonnensystem abfragt

Alien: Computer, bitte sag mir alle Planeten, auf denen Menschen leben.

Computer: 1 Ergebnis gefunden. Erde

Alien: Computer, bitte erzähl mir von Erde .

Computer: Erde - größtenteils harmlos.

Alien: Computer, bitte erzähl mir von allen Planeten, die Menschen außerhalb des Asteroidengürtels bewohnen.

Computer: 0 Ergebnisse gefunden.

Alien: Computer, bitte zerstöre die Erde.

Computer: 200 OK.

Alien: Computer, bitte erzähl mir von Erde .

Computer: 404 - Nicht gefunden

Alien: Computer, bitte sag mir alle Planeten, auf denen Menschen leben.

Computer: 0 Ergebnisse gefunden.

Alien: Sieg für das mächtige Irken-Reich!

85
user69037

Wenn Sie die Tatsache ignorieren, dass/GoalTree/Get * wie ein Verb und nicht wie Ressourcen aussieht, sollten Sie immer 200 zurückgeben, da URI/GoalTree/Get * Ressourcen darstellen, die immer für den Zugriff verfügbar sind, und es kein Clientfehler ist, wenn kein Baum vorhanden ist eine Anfrage. Geben Sie einfach 200 mit leerem Satz zurück, wenn keine Entität zurückgegeben werden soll.

Sie verwenden 404, wenn die Ressource nicht gefunden wird, nicht, wenn keine Entität vorhanden ist.

Anders ausgedrückt: Wenn Sie 404 für Ihre Objekte zurückgeben möchten, geben Sie ihnen ihre eigenen URIs.

12
imel96

Dies ist eine interessante Frage, da es nur um die Systemspezifikation geht.

imel96's response hat mich überzeugt, dass ein 404 keine richtige Antwort wäre, da die 4xx-Codefamilie hauptsächlich für Benutzer-/Client-Fehler , und das ist keiner. Die URL ist wohlgeformt und der Baum muss vorhanden sein. Ist dies nicht der Fall, befindet sich das System in einem inkonsistenten Zustand!

Daher ist dies ein Serverfehler , d. H. Etwas in der 5xx-Familie. Möglicherweise ein generischer 500 Internal Server Error oder ein 503 Service nicht verfügbar (der Dienst lautet "Hol mir den Baum, der da sein muss").

8
Andres F.

Ich würde sagen, dass entweder ein 200- oder ein 404-Antwortcode gültig sein kann , je nachdem, wie Sie die Situation betrachten.

Die Sache ist, dass HTTP-Antwortcodes im Kontext eines Servers definiert sind, der basierend auf seiner URL verschiedene Ressourcen liefern kann . In diesem Zusammenhang sind die Bedeutungen von 200 OK und 404 Not Found sind absolut eindeutig: Ersteres sagt "Hier ist die Ressource, nach der Sie gefragt haben", während Letzteres sagt "Entschuldigung, ich habe keine solche Ressource".

In Ihrer Situation haben Sie jedoch eine zusätzliche Anwendung Schicht zwischen dem HTTP-Server und den tatsächlichen Ressourcen (Bäumen), die angefordert werden. Die Anwendung belegt eine Art Zwischenraum, der in der HTTP-Spezifikation nicht gut angesprochen wird.

Aus Sicht des Webservers sieht die Anwendung irgendwie wie eine Ressource aus: Es handelt sich normalerweise um eine Datei auf dem Server, die durch (einen Teil) der URL identifiziert wird, genau wie andere Ressourcen (z. B. statische Dateien). Der Server könnte dienen. Auf der anderen Seite handelt es sich um eine seltsame Art von Ressource, da sie aus ausführbarem Code besteht, der den Inhalt und möglicherweise sogar den Statuscode der Antwort dynamisch bestimmt und sich in gewisser Weise eher wie ein Miniserver verhält.

Insbesondere in Ihrem Beispielfall kann der Webserver die Anwendung problemlos finden, aber die Anwendung kann dann die angeforderte Unterressource (Baum) nicht finden. Wenn Sie nun die Anwendung als nur Erweiterung des Servers und das Unterelement (Baum) als tatsächliche Ressource betrachten, dann ist a 404 Antwort ist angemessen: Der Server hat lediglich die Aufgabe, die tatsächliche Ressource zu finden, an die Anwendung delegiert, was er wiederum nicht getan hat.

Wenn Sie jedoch der Ansicht sind, dass die Anwendung die angeforderte Ressource ist, sollte der Webserver offensichtlich eine 200-Antwort zurückgeben ); Immerhin wurde die Anwendung gefunden und korrekt ausgeführt. In diesem Fall sollte die Anwendung offensichtlich einen gültigen Antworttext im erwarteten Format zurückgeben, der angibt (unter Verwendung des übergeordneten Protokolls, das das Format codiert), dass keine tatsächlichen Daten gefunden wurden, die mit der Abfrage übereinstimmen.

Beide Gesichtspunkte können sinnvoll sein. In den meisten Fällen , zumindest für Anwendungen, auf die mit einem normalen Webbrowser direkt über HTTP zugegriffen werden soll, würde ich die frühere Ansicht bevorzugen : Der Benutzer kümmert sich im Allgemeinen nicht um interne Details wie den Unterschied zwischen dem Server und der Anwendung, sondern nur darum, ob die gewünschten Daten vorhanden sind oder nicht.

Im speziellen Fall einer Anwendung, die für die Kommunikation mit anderen Computerprogrammen unter Verwendung eines benutzerdefinierten API-Protokolls auf hoher Ebene unter Verwendung von HTTP nur als Transportschicht auf niedriger Ebene entwickelt wurde, gibt es eine Argument für die letztere Ansicht : Für Clients, die mit einer solchen Anwendung verbunden sind, ist alles, was sie wirklich interessiert, auf HTTP-Ebene ist, ob es ihnen gelungen ist, die Anwendung erfolgreich zu kontaktieren oder nicht. Alles andere wird in solchen Fällen oft natürlicher über das übergeordnete Protokoll kommuniziert.


Unabhängig davon, welche der oben genannten Ansichten Sie bevorzugen, sollten Sie auf jeden Fall einige Details beachten. Zum einen kann es in vielen Fällen eine sinnvolle Unterscheidung zwischen einer (im Wesentlichen) leeren Ressource und einer nicht vorhandenen Ressource geben.

Auf der HTTP-Ebene würde eine leere Ressource einfach durch einen 200-Antwortcode und einen leeren Antworttext angezeigt, während eine nicht vorhandene Ressource durch eine 404-Antwort und einen Ressourcenkörper angezeigt würde, die das Fehlen der Ressource erklären. In einem übergeordneten API-Protokoll würde man normalerweise eine nicht vorhandene Ressource durch eine Fehlerantwort anzeigen, die einen geeigneten protokollspezifischen Fehlercode/eine geeignete protokollspezifische Nachricht enthält, während eine leere Antwort einfach eine normale Antwortstruktur ohne Datenelemente wäre.

(Beachten Sie, dass eine Ressource nicht buchstäblich null Byte lang sein muss, um im oben genannten Sinne "leer" zu sein. Beispielsweise würde ein Suchergebnis ohne übereinstimmende Elemente im weiteren Sinne als leer gelten, ebenso wie ein SQL-Abfrageergebnis mit keine Zeilen oder ein XML-Dokument, das keine tatsächlichen Daten enthält.)

Wenn die Anwendung wirklich glaubt, dass die angeforderte Unterressource sollte vorhanden ist, sie aber nicht finden kann, existiert natürlich ein dritter möglicher Antwortcode: 500 Internal Server Error. Eine solche Antwort ist sinnvoll, wenn das Vorhandensein der Ressource eine angenommene Voraussetzung für die Anwendung ist, sodass ihre Abwesenheit notwendigerweise auf eine interne Fehlfunktion hinweist.

Schließlich sollten Sie immer im Auge behalten Postels Gesetz :

" Sei konservativ in dem, was du sendest, und liberal in dem, was du empfängst."

Ob der Server sollte in einer bestimmten Situation mit einer Antwort von 200 oder 404 antwortet, das entschuldigt Sie als Client Implementierer von der angemessenen Behandlung einer der Antworten und auf eine Weise, die eine robuste Interoperabilität maximiert. Natürlich kann argumentiert werden, was "angemessenes" Handling in verschiedenen Situationen bedeutet, aber es sollte normalerweise kein Absturz oder sonstiges "Auseinanderfallen" beinhalten.

6
Ilmari Karonen

Wenn die URL eine Ressource darstellt, die nie existiert hat, geben Sie 404 Not Found zurück

Wenn die URL eine Ressource darstellt, die eine leere Liste ist, geben Sie eine leere Liste und 200 OK zurück.

Beispiel:

{
  total: 0,
  items: []
}

Wenn die URL eine Ressource darstellt, die früher vorhanden war, geben Sie 410 Gone zurück.

Zum Dialog von Lego Stormtrooper:

Alien: Computer, please tell me all planets that humans inhabit. GET /planets?inhabitedBy=humans

Computer: 200 OK. { total: 1, items:[{name:'Earth'}] }

Alien: Computer, please tell me about Earth. GET /planets/earth

Computer: 200 OK. {name:'Earth', status: 'Mostly Harmless'}

Alien: Computer, please tell me about all planets humans inhabit, outside the asteroid belt. GET /planets?inhabitedBy=humans&distanceFromSun=lots

Computer: 200 OK. {total:0, items:[] }

Alien: Computer, please destroy Earth. DELETE /planets/earth

Computer: 204 No Content. (or 202 Accepted if it takes some time to destroy Earth)

Alien: Computer, please tell me about Earth. GET /planets/earth

Computer: 410 Gone

Alien: Computer, please tell me all planets that humans inhabit. GET /planets?inhabitedBy=humans

Computer: 200 OK 0 {total: 0, items:[] }

Alien: Victory for the mighty Irken Empire!
3
Neil McGuigan

Wie wäre es mit einem 204 No Content? Es würde bedeuten, dass Ihre Anfrage erfolgreich verarbeitet wurde, aber nichts zurückgibt. Es ist immer noch ein "Erfolg", aber Sie können sehen, ob Sie Ergebnisse nur anhand des Statuscodes haben.

3
modernserf

Nach dem Sound ist dies eine API für intern Verwendung. Dies gibt den Vorteil, dass jedes Schema verwendet werden kann, das am meisten Nutzen bietet, unabhängig davon, ob es sich um ein Buch handelt (Spezifikation) oder nicht. Dies bedeutet nicht, dass Sie Ihre eigenen Statuscodes vollständig erfinden müssen, aber es ist in Ordnung, die Regeln ein wenig zu "biegen", wenn dies von Vorteil ist.

Ich stimme Ihrem Standpunkt zu, dass Sie einen Statuscode erhalten sollten, der anzeigt, dass etwas schief gelaufen ist. Dies ist schließlich, wofür Statuscodes sind. Sie profitieren auch von Bibliotheken, die Ausnahmen/etc. Auslösen. auf Nicht-200-Statuscode, damit Sie nicht explizit prüfen müssen (oder Sie können Ihren eigenen Wrapper schreiben, der dies tut).

Ich stimme auch dem Standpunkt von Andres F. zu, dass 500 angemessen ist, da der Baum sollte existiert. In der Praxis teile ich Serverfehler gerne in zwei Kategorien ein. Etwas Unerwartetes ist schiefgegangen und etwas, auf das ich praktisch prüfen kann, ist schiefgegangen. Dies führt zu den folgenden Statuscodes:

  • 200 - Alles ist gut
  • 404 - Falsche URL
  • 409 - Etwas ist schief gelaufen
  • 500 - Auf dem Server ist ein unerwarteter Fehler aufgetreten

In Ihrem speziellen Fall können Sie überprüfen, ob der Baum auf der Serverseite vorhanden ist oder nicht. Wenn er nicht vorhanden ist, geben Sie einen 409 zurück. Es handelt sich um einen erwarteten Fehler (Sie wissen, dass dies passieren kann, Sie können ihn überprüfen usw.). . 409 Konflikt ist nur meine persönliche Präferenz, ein 5xx kann auch angebracht sein, solange Sie sich hinsetzen und dies mit Ihrem Team entscheiden können.

Das Kategorisieren solcher Codes hilft Ihnen dabei, die Art des Fehlers schneller zu identifizieren, kann jedoch über die Organisation hinaus Vorteile haben. Bei Website-Fehlern möchten Sie häufig nicht, dass der Client unerwartete Fehler erhält, da dies ein Sicherheitsrisiko darstellen und Schwachstellen aufdecken kann, sodass Sie eine generische 500 zurückgeben. "Ein Fehler ist aufgetreten." und protokollieren Sie den vollständigen Fehler auf dem Server. Wenn jedoch ein erwarteter Fehler als 409 auftritt, wissen Sie, dass es sicher ist, den Fehler dem Client anzuzeigen, und Sie müssen ihn nicht im Dunkeln lassen, was passiert ist. Dies ist nur eine praktische Anwendung, die ich wiedergeben kann, aber es gibt viele Möglichkeiten.

Dies ist ein kleiner Haken, weil Sie dies veröffentlichen, weil Sie nicht in der Lage sind, Ihren Kollegen zuzustimmen, aber es hört sich so an, als würden Sie mehr über Semantik streiten und wer politisch korrekt ist. Es spielt wirklich keine Rolle, wer besser ist, solange Sie ein System entwickeln können, das dem Unternehmen am meisten zugute kommt.

Auf der anderen Seite wäre es wichtiger, wenn dies eine öffentliche API ist, die den Spezifikationen so genau wie möglich folgt, um Verwirrung in der Community zu vermeiden.

1
Despertar

404 == Der Client hat auf eine "individuelle"/"konkrete" Ressource verwiesen, die nicht vorhanden ist. Das ist ein Clientfehler.

200 == Der Client hat angefordert, eine Reihe von "konkreten" Ressourcen zu erstellen. Ein Set kann immer auch leer sein. Selbst wenn die Sammlung (Abfrageergebnis) leer ist, hat der Client keinen Fehler gemacht.

0
Dave

Ein tangentialer Versuch: Wenn ein Mensch irgendwann die API verwendet (über eine grafische Benutzeroberfläche), würde ich vorschlagen, alles zu tun, was dem Endbenutzer das Leben leichter macht. Das Nichtvorhandensein des Baums, wenn er vorhanden sein sollte, ist ein Fehler "Domänenmodellinkonsistenz". Ein Systemfehler liegt vor, wenn Ihnen der Arbeitsspeicher ausgeht oder ein anderer Systemfehler aufgetreten ist. Die Rückgabe von 5xx ist daher unangemessen. Wie oben von mehreren Leuten erwähnt, könnte 4xx angemessen sein, wenn der Baum selbst eine eigene URI hätte, was hier nicht der Fall ist. Aber hier ist, was 404 dem Kunden sagt: Sie können es immer wieder versuchen, bis Sie etwas zurückbekommen. Wenn Sie 200 zurückgegeben haben, können Sie dem Benutzer oder Benutzeragenten eine ausreichende Diagnose zurückgeben, sodass der Benutzeragent eine Messung anzeigen kann, sodass der Benutzer die Wiederholung beendet und nur den Support kontaktiert. Wenn diese API jedoch nur für Systeme bestimmt ist, muss eine "Ausnahmemeldung" Teil der API sein, damit Sie sich nicht auf die inhärente Unbestimmtheit von HTTP-Fehlercodes verlassen müssen und etwas Sinnvolles zurückgeben können, das dies kann vom Verbraucher protokolliert und eskaliert werden.

0
user90766