Ich arbeite an einem Projekt und nachdem ich mich mehr als eine Stunde mit Leuten bei der Arbeit gestritten habe. Ich entschied mich zu wissen, was die Leute auf Stack-Exchange sagen könnten.
Wir schreiben eine API für ein System. Es gibt eine Abfrage, die einen Baum der Organisation oder einen Baum der Ziele zurückgeben soll.
Der Baum der Organisation ist die Organisation, in der sich der Benutzer befindet. Mit anderen Worten, dieser Baum sollte immer vorhanden sein. In der Organisation sollte immer ein Zielbaum vorhanden sein. (Hier hat das Argument angefangen). Für den Fall, dass der Baum nicht vorhanden ist, entschied mein Mitarbeiter, dass es richtig wäre, die Antwort mit dem Statuscode 200 zu beantworten. Dann bat er mich, den Code zu korrigieren, da die Anwendung auseinanderfiel, wenn es keinen Baum gab.
Ich werde versuchen, Flammen und Wut zu ersparen.
Ich schlug vor, einen 404-Fehler auszulösen, wenn kein Baum vorhanden ist. Zumindest würde es mich wissen lassen, dass etwas nicht stimmt. Bei der Verwendung von 200 muss ich meine Antwort im Erfolgs-Callback besonders prüfen, um Fehler zu behandeln. Ich erwarte, ein Objekt zu erhalten, erhalte jedoch möglicherweise eine leere Antwort, da nichts gefunden wird. Es klingt absolut 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. Ich bin also hier und frage, was in diesem Fall mit 404 nicht stimmt. 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 eingeben, wird die erste Revision zurückgegeben. Wenn von ID mit einer ID, die nicht vorhanden ist, ich vermute, es wird eine leere Antwort mit 200 zurückgeben.
Extra
Ich glaube auch, dass die beste Antwort auf das Problem darin besteht, Standardobjekte zu erstellen, wenn Organisationen erstellt werden. Wenn kein Baum vorhanden ist, sollte dies 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 präsent sein.
Auch ich habe dies verlinkt (eine ähnliche, aber ich kann es nicht finden)
http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png
quelle
/GoalTree/GetById?versionId=CompletelyInvalidID
zurückkehren? Kein Erfolg, da die angegebene Ressource/GoalTree/GetById?versionId=CompletelyInvalidID
buchstäblich nicht gefunden wurde.Antworten:
Im Zweifelsfall konsultieren Sie die Dokumentation . Wenn wir die W3C-Definitionen für HTTP-Statuscodes überprüfen, erhalten wir Folgendes:
Im Kontext Ihrer API hängt es sehr davon ab, wie Abfragen erstellt und wie Objekte abgerufen werden. Meine Interpretation war jedoch immer:
200
, geben Sie den richtigen404
Code zurück , wenn es nicht existiert .200
Code zurückgegeben werden soll. Der Grund dafür ist, dass die Abfrage gültig war, erfolgreich war und nichts zurückgegeben wurde.In diesem Fall haben Sie also Recht , der Dienst sucht nicht nach "einer bestimmten Sache", sondern fordert eine bestimmte Sache an, wenn diese Sache nicht gefunden wird, sagen Sie dies deutlich.
Ich denke, Wikipedia bringt es am besten auf den Punkt:
Scheint mir ziemlich klar.
Zu den Beispielanfragen
Für das Format, sagten Sie, geben Sie immer die nächste Revision zu diesem Datum zurück. Ein Objekt wird niemals nicht zurückgegeben, daher sollte es immer zurückgegeben werden
200 OK
. Selbst wenn dies in der Lage wäre, einen Datumsbereich einzunehmen, und die Logik wäre, alle Objekte innerhalb dieses Zeitrahmens mit 200 OK zurückzugeben - 0 Ergebnisse sind in Ordnung, da dies der Zweck der Anfrage ist - die Menge der Dinge, die diese Kriterien erfüllen.Letzteres ist jedoch anders, da Sie nach einem bestimmten Objekt fragen , das mit dieser Identität vermutlich eindeutig ist.
200 OK
In diesem Fall ist die Rückgabe falsch, da die angeforderte Ressource nicht vorhanden ist und nicht gefunden wird .Bezüglich der Auswahl von Statuscodes
Sie haben in einem Kommentar einen 5xx-Code angegeben, aber Ihr System funktioniert. Es wurde eine Abfrage gestellt, die nicht funktioniert und der UA mitgeteilt werden muss. Egal wie Sie es schneiden, das ist 4xx Gebiet.
Stellen Sie sich einen Außerirdischen vor, der unser Sonnensystem abfragt
quelle
Wenn Sie die Tatsache ignorieren, dass / GoalTree / Get * wie ein Verb und nicht wie Ressourcen aussieht, sollten Sie immer 200 zurückgeben, da der URI / GoalTree / Get * Ressourcen darstellt, auf die immer zugegriffen werden kann, 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 muss.
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.
quelle
/GoalTree/GetById?versionId=12345
ist ein perfekter URI (zumindest ein relativer URI), der eine bestimmte Ressource identifiziert, nämlich die Daten, die der Versions-ID12345
im System entsprechen. Wenn keine Daten mit einer solchen ID vorhanden sind, ist eine 404-HTTP-Antwort vollkommen angemessen. Natürlich sollte der Antworttext in jedem Fall eine entsprechend formatierte Antwort enthalten (z. B. JSON, wenn dies von typischen Clients erwartet wird, die solche Ressourcen anfordern), die die spezifische Art und Ursache des Fehlers angibt.Dies ist eine interessante Frage, da es um die Spezifikation des Systems geht.
Die Antwort von imel96 hat mich überzeugt, dass ein 404 keine richtige Antwort ist, da die 4xx-Familie von Codes hauptsächlich für Benutzer- / Client-Fehler ist , und dies ist keine. Die URL ist wohlgeformt und der Baum muss da sein. Ist dies nicht der Fall, befindet sich das System in einem inkonsistenten Zustand!
Daher ist dies ein Server - Fehler, also etwas in der 5xx Familie. Möglicherweise ist ein generischer 500 Internal Server Error oder ein 503 Service nicht verfügbar (der Service lautet "Hol mir den Baum, der da sein muss").
quelle
Ich würde sagen, dass entweder ein 200er oder ein 404er Antwortcode gültig sein kann , je nachdem, wie Sie die Situation sehen.
Die Sache ist, dass HTTP-Antwortcodes im Kontext eines Servers definiert werden , der verschiedene Ressourcen basierend auf ihrer URL bereitstellen kann. In diesem Zusammenhang sind die Bedeutungen von
200 OK
und404 Not Found
völlig eindeutig: Ersterer sagt "Hier ist die Ressource, nach der Sie gefragt haben", während Letzterer sagt "Entschuldigung, ich habe keine solche Ressource".In Ihrer Situation haben Sie jedoch eine zusätzliche Anwendungsschicht 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 ausreichend behandelt wird.
Aus Sicht des Webservers, sieht die Anwendung Art wie eine Ressource: es ist in der Regel eine Datei auf dem Server, identifiziert durch (ein Teil) die URL, wie andere Ressourcen (zB statische Dateien) der Server dienen könnte. 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, wodurch sie sich in gewisser Weise eher wie ein Miniserver verhält.
In Ihrem Beispielfall kann der Webserver die Anwendung zwar problemlos finden, die angeforderte Subressource (Baumstruktur) kann jedoch nicht gefunden werden. Wenn Sie die Anwendung nur als Erweiterung des Servers und das Unterelement (Baum) als tatsächliche Ressource betrachten, ist eine 404-Antwort angemessen: Der Server hat lediglich die Aufgabe delegiert, die tatsächliche Ressource an die Anwendung zu ermitteln , was es wiederum nicht geschafft hat.
Wenn Sie dagegen der Ansicht sind, dass die Anwendung die angeforderte Ressource ist, sollte der Webserver offensichtlich eine Antwort von 200 zurückgeben . Immerhin wurde die Anwendung gefunden und korrekt ausgeführt. In diesem Fall sollte die Anwendung natürlich einen gültigen Antworttext im erwarteten Format zurückgeben, der angibt (unter Verwendung des übergeordneten Protokolls, das vom Format codiert wird), dass keine tatsächlichen Daten gefunden wurden, die mit der Abfrage übereinstimmen.
Beide Standpunkte können sinnvoll sein. In den meisten Fällen würde ich , zumindest für Anwendungen, auf die mit einem normalen Webbrowser direkt über HTTP zugegriffen werden soll, die vorherige Ansicht bevorzugen : Der Benutzer interessiert sich im Allgemeinen nicht für interne Details wie den Unterschied zwischen dem Server und der Anwendung, sondern nur dafür kümmern sich darum, ob die gewünschten Daten vorhanden sind oder nicht.
In dem speziellen Fall einer Anwendung, die für die Kommunikation mit anderen Computerprogrammen unter Verwendung eines benutzerdefinierten API-Protokolls auf hoher Ebene entwickelt wurde und HTTP nur als Transportschicht auf niedriger Ebene verwendet , ist jedoch ein Argument für die letztere Ansicht zu sprechen : z Clients, die mit einer solchen Anwendung kommunizieren, kümmern sich auf HTTP-Ebene nur darum, 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 in jedem Fall einige Details beachten. Zum einen kann es in vielen Fällen eine sinnvolle Unterscheidung zwischen einer (im Wesentlichen) leeren und einer nicht vorhandenen Ressource geben .
Auf der HTTP-Ebene würde eine leere Ressource einfach durch einen Antwortcode 200 und einen leeren Antworttext angezeigt, während eine nicht vorhandene Ressource durch eine Antwort 404 und einen Ressourcentext 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 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 eine SQL-Abfrage mit keine Zeilen oder ein XML-Dokument, das keine tatsächlichen Daten enthält.)
Auch natürlich, wenn die Anwendung wirklich glaubt , dass die angeforderte subresource sollte da sein, aber kann es nicht finden, dann eine dritte mögliche Antwortcode vorhanden ist :
500 Internal Server Error
. Eine solche Reaktion ist sinnvoll, wenn das Vorhandensein der Ressource eine vorausgesetzte Voraussetzung für die Anwendung ist, so dass deren Fehlen zwangsläufig auf eine interne Fehlfunktion hinweist.Schließlich sollten Sie immer das Postelsche Gesetz beachten :
Ob der Server sollte in einer bestimmten Situation mit einem 200 oder einer 404 - Antwort reagieren, das nicht entschuldigt Sie als Client - Implementierer von der Handhabung entweder Reaktion in geeigneter Weise und in der Art und Weise , die robuste Interoperabilität maximiert. Natürlich kann argumentiert werden, was "angemessenes" Handling in verschiedenen Situationen bedeutet, aber normalerweise sollte es nicht zum Absturz oder anderweitigen "Auseinanderbrechen" kommen.
quelle
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 anhand des Statuscodes allein feststellen, ob Ergebnisse vorliegen.
quelle
Wenn die URL eine nie existierende Ressource darstellt, 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:
Wenn die URL eine Ressource darstellt, die zuvor vorhanden war, geben Sie 410 Gone zurück.
Zum Dialog von Lego Stormtrooper:
quelle
Dem Klang nach ist dies eine API für den internen Gebrauch. Dies bietet den Vorteil , dass Sie das Schema verwenden können, das den größten Nutzen bringt , unabhängig davon, ob es sich um ein Standardschema (Spezifikation) handelt 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 ändern, wenn dies von Vorteil ist.
Ich stimme Ihrem Stand zu, dass Sie einen Statuscode erhalten sollten, der anzeigt, dass etwas schief gelaufen ist. Dies ist schließlich, was Statuscodes sind. Außerdem profitieren Sie von Bibliotheken, die Ausnahmen / etc. Auslösen. auf Nicht-200-Statuscode, damit Sie nicht explizit überprü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 existieren sollte . 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. Daraus ergeben sich folgende Statuscodes:
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 eine 409 zurück. Es handelt sich um einen erwarteten Fehler (Sie wissen, dass er auftreten kann, Sie können ihn überprüfen usw.). . 409 Konflikt ist nur meine persönliche Präferenz, ein 5xx kann auch angemessen sein, solange Sie sich setzen und dies mit Ihrem Team entscheiden können.
Wenn Sie Codes wie diesen kategorisieren, können Sie den Fehlertyp schneller identifizieren, dies kann jedoch auch über die Organisation hinaus Vorteile haben. Bei Website-Fehlern soll der Client häufig keine unerwarteten Fehler erhalten, da dies ein Sicherheitsrisiko darstellt und Sicherheitslücken aufdeckt, sodass Sie eine generische Zahl von 500 "Ein Fehler ist aufgetreten" zurückgeben. 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, von der ich berichten 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 klingt, als ob Sie sich mehr über Semantik streiten und wer politisch korrekt ist. Es ist wirklich egal, wer der Richtige ist, solange Sie ein System entwickeln können, von dem das Unternehmen am meisten profitiert.
Wenn es sich jedoch um eine öffentliche API handelt, bei der die Spezifikationen so genau wie möglich eingehalten werden, ist dies wichtiger, um Verwirrung in der Community zu vermeiden.
quelle
Wenn ein Mensch irgendwann die API (über eine GUI) verwendet, würde ich vorschlagen, alles zu tun, was dem Endbenutzer das Leben leichter macht. Die Nichtexistenz des Baums, wenn er vorhanden sein sollte, ist ein Fehler "Domänenmodell-Inkonsistenz". Ein Systemfehler liegt vor, wenn Ihnen der Speicher ausgeht oder ein anderer Systemfehler aufgetreten ist. Daher ist es unangemessen, 5xx zurückzugeben. Wie oben von mehreren Leuten erwähnt, könnte 4xx angemessen sein, wenn der Baum selbst eine eigene URI hat, 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 genügend Diagnosen zurückgeben, damit der Benutzeragent eine Meldung anzeigen kann, damit der Benutzer den erneuten Versuch abbricht und sich nur an den Support wendet. Auf der anderen Seite, wenn diese API nur für Systeme bestimmt ist,
quelle