545 Stimmen

Was ist der richtige REST-Antwortcode für eine gültige Anfrage, aber leere Daten?

Sie führen zum Beispiel eine GET-Anfrage für users/9 aber es gibt keinen Benutzer mit der ID #9. Welches ist der beste Antwortcode?

  • 200 OK
  • 202 Angenommen
  • 204 Ohne Inhalt
  • 400 Schlechte Anfrage
  • 404 nicht gefunden

3voto

Filipe Moisés Punkte 31

Nach dem RFC7231 - Seite59( https://www.rfc-editor.org/rfc/rfc7231#page-59 ) die Definition der 404-Statuscode-Antwort lautet:

6.5.4. 404 Nicht gefunden Der Statuscode 404 (Not Found) zeigt an, dass der Ursprungsserver keine aktuelle Darstellung für die Zielressource gefunden hat oder nicht nicht bereit ist, das Vorhandensein einer Repräsentation bekannt zu geben. Ein 404-Statuscode sagt nichts darüber aus nicht an, ob diese fehlende Darstellung vorübergehend oder dauerhaft ist. dauerhaft ist; der Statuscode 410 (Gone) wird gegenüber 404 bevorzugt, wenn der Ursprungsserver weiß, vermutlich durch einige konfigurierbare Mittel, dass der Zustand wahrscheinlich dauerhaft sein wird. Eine 404-Antwort ist standardmäßig zwischenspeicherbar, d. h., wenn nicht anders angegeben durch die Methodendefinition oder explizite Cache-Kontrollen angegeben (siehe Abschnitt 4.2.2 von [RFC7234]).

Der wichtigste Punkt, der Zweifel aufkommen lässt, ist die Definition von Ressource im obigen Kontext. Laut demselben RFC (7231) lautet die Definition von Ressource:

Ressourcen: Das Ziel einer HTTP-Anfrage wird als "Ressource" bezeichnet. HTTP schränkt nicht schränkt die Art einer Ressource nicht ein; es definiert lediglich eine Schnittstelle, die für die Interaktion mit Ressourcen verwendet werden kann. Jede Ressource wird durch einen Uniform Resource Identifier (URI) identifiziert, wie in Abschnitt 2.7 von [RFC7230] beschrieben. Wenn ein Client eine HTTP/1.1-Anforderungsnachricht erstellt, sendet er den Ziel-URI in einer der verschiedenen Formen, wie sie in Abschnitt 5.3 von [RFC7230]). Wenn eine Anfrage empfangen wird, rekonstruiert der Server einen effektive Anfrage-URI für die Zielressource (Abschnitt 5.5 von [RFC7230]). Ein Designziel von HTTP ist die Trennung der Ressourcenidentifikation von von der Anfragesemantik zu trennen, was durch die Verankerung der Anfragesemantik Semantik in der Anfragemethode (Abschnitt 4) und einigen Anfrage modifizierenden Header-Feldern (Abschnitt 5). Wenn es einen Konflikt gibt zwischen der Methodensemantik und einer durch den URI implizierten Semantik selbst impliziert wird, wie in Abschnitt 4.2.1 beschrieben, wird die Methodensemantik Vorrang.

Nach meinem Verständnis sollte der 404-Statuscode nicht bei einer erfolgreichen GET-Anfrage mit leerem Ergebnis verwendet werden (Beispiel: eine Liste ohne Ergebnis für einen bestimmten Filter).

3voto

wombatonfire Punkte 3514

Die Antworten in diesem Thread (26 zum Zeitpunkt der Erstellung dieses Artikels) veranschaulichen perfekt, wie wichtig es für einen Entwickler ist, die Semantik der Konstrukte zu verstehen, mit denen er arbeitet.

Ohne dieses Verständnis ist es vielleicht nicht offensichtlich, dass Antwortstatuscodes Eigenschaften einer Antwort sind und nichts anderes. Diese Codes existieren im Kontext der Antwort, und ihre Bedeutung außerhalb dieses Kontexts ist undefiniert.

Die Antwort selbst ist das Ergebnis der Anfrage. Die Anfrage wirkt auf Ressourcen. Ressourcen, Anfragen, Antworten und Statuscodes sind die Konstrukte von HTTP, und soweit es HTTP betrifft:

HTTP bietet eine einheitliche Schnittstelle für die Interaktion mit einer Ressource (Abschnitt 2), unabhängig von ihrem Typ, ihrer Beschaffenheit oder ihrer Implementierung, über die Manipulation und Übertragung von Darstellungen (Abschnitt 3). Quelle .

Mit anderen Worten, der Bereich der Antwortstatuscodes wird durch eine Schnittstelle begrenzt, die sich nur um einige Zielressourcen kümmert und sich mit Nachrichten befasst, die zur Interaktion mit diesen Ressourcen verwendet werden. Die Anwendungslogik des Servers liegt außerhalb des Geltungsbereichs, und auch die Daten, mit denen Sie arbeiten, sind nicht von Bedeutung.

Wenn HTTP verwendet wird, wird es immer mit Ressourcen verwendet. Die Ressourcen werden entweder übertragen oder manipuliert. Solange wir uns nicht in einer Quantenwelt befinden, existiert die Ressource entweder oder sie existiert nicht, es gibt keinen dritten Zustand.

Wenn eine HTTP-Anfrage zum Abrufen (Übertragen) der Darstellung der Ressource (wie in dieser Frage) gestellt wird und die Ressource nicht existiert, sollte das Ergebnis der Antwort einen Fehler mit dem entsprechenden 404-Code anzeigen. Das Ziel - das Abrufen der Darstellung - wurde nicht erreicht, die Ressource wurde nicht gefunden. Es sollte keine andere Interpretation des Ergebnisses im Zusammenhang mit dem HTTP geben.

RFC 7231 Hypertext-Übertragungsprotokoll (HTTP/1.1): Semantik und Inhalt wurde hier mehrfach erwähnt, aber hauptsächlich als Referenz für die Beschreibung des Statuscodes. Ich empfehle dringend, das gesamte Dokument zu lesen, und nicht nur Abschnitt 6, um ein besseres Verständnis des Umfangs und der Semantik der HTTP-Schnittstelle und ihrer Komponenten zu erhalten.

3voto

James Punkte 4481

Solche Dinge können subjektiv sein, und es gibt einige interessante und verschiedene solide Argumente auf beiden Seiten. Allerdings [meiner Meinung nach] die Rückgabe einer 404 für fehlende Daten ist nicht korrekt . Um dies zu verdeutlichen, hier eine vereinfachte Beschreibung:

  • Anfrage: Kann ich bitte einige Daten erhalten?
  • Ressource (API-Endpunkt): Ich hole diese Anfrage für Sie ab, hier [sendet eine Antwort mit potenziellen Daten]

Nichts ist kaputt gegangen, der Endpunkt wurde gefunden, und die Tabelle und die Spalten wurden gefunden, so dass die DB abgefragt und die Daten "erfolgreich" zurückgegeben wurden!

Nun - ob diese "erfolgreiche Antwort" Daten enthält oder nicht, spielt keine Rolle. Sie haben um eine Antwort mit "potenziellen" Daten gebeten und diese Antwort mit "potenziellen" Daten wurde erfüllt. Null, leer usw. sind gültige Daten.

200 bedeutet nur, dass die Anfrage erfolgreich war, egal was wir gemacht haben. Ich fordere Daten an, bei HTTP/REST ist nichts schiefgelaufen, und da Daten (wenn auch leere) zurückgegeben wurden, war meine "Anforderung von Daten" erfolgreich.

Geben Sie eine 200 zurück und überlassen Sie es dem Anfragenden, sich mit leeren Daten zu befassen, wie es das jeweilige Szenario erfordert!

Betrachten Sie dieses Beispiel:

  • Anfrage: Abfrage der Tabelle "Ordnungswidrigkeiten" mit der Benutzer-ID 1234
  • Ressource (API-Endpunkt): Gibt eine Antwort zurück, aber die Daten sind leer

Dass diese Daten leer sind, ist völlig richtig. Es bedeutet, dass der Benutzer keine Verstöße hat. Dies ist eine 200 als es ist alles gültig, wie dann kann ich tun:

Sie haben keine Verstöße, essen Sie einen Blaubeermuffin!

Wenn Sie dies für eine 404 halten, was geben Sie an? Die Verstöße des Benutzers konnten nicht gefunden werden? Nun, grammatikalisch ist das korrekt, aber in der REST-Welt, in der der Erfolg oder Misserfolg von der Anfrage abhängt, ist es einfach nicht korrekt. Die "Verstoß"-Daten für diesen Benutzer konnten erfolgreich gefunden werden, es gibt null Verstöße - eine echte Zahl, die einen gültigen Zustand darstellt.


[Freche Bemerkung ]

In Ihrem Titel stimmen Sie unbewusst zu, dass 200 die richtige Antwort ist:

Was ist der richtige REST-Antwortcode für eine gültige Anfrage sondern eine leere Datei?


Hier sind einige Dinge, die bei der Wahl des zu verwendenden Statuscodes zu beachten sind, ungeachtet der Subjektivität und der kniffligen Wahlmöglichkeiten:

  1. Konsistenz . Wenn Sie 404 für "keine Daten" verwenden, verwenden Sie es jedes Mal eine Antwort keine Daten zurückgibt.
  2. Verwenden Sie nicht denselben Status für mehr als eine Bedeutung . Wenn Sie 404 zurückgeben, wenn eine Ressource nicht gefunden wurde (z. B. API-Endpunkt existiert nicht usw.), dann nicht auch verwenden, wenn keine Daten zurückgegeben werden. Dies macht nur den Umgang mit Antworten ein Schmerz.
  3. Berücksichtigen Sie den Kontext sorgfältig . Was ist die "Bitte"? Was sagen Sie, was Sie erreichen wollen?

3voto

dariok Punkte 189

Ich würde sagen, beides ist nicht wirklich angemessen. Wie bereits gesagt wurde - z.B. von @anneb - denke auch ich, dass ein Teil der Probleme aus der Verwendung eines HTTP-Antwortcodes zur Übermittlung eines Status in Bezug auf einen RESTful-Dienst resultiert. Alles, was der REST-Dienst über seine eigene Verarbeitung mitzuteilen hat, sollte mit Hilfe von REST-spezifischen Codes transportiert werden.

1

Wenn der HTTP-Server einen Dienst findet, der bereit ist, eine Anfrage zu beantworten, sollte er nicht mit einem HTTP 404 antworten - schließlich hat der Server etwas gefunden -, es sei denn, der Dienst, der die Anfrage bearbeitet, sagt dies ausdrücklich.

Nehmen wir für einen Moment die folgende URL an: http://example.com/service/return/test .

  • In Fall A sucht der Server "einfach nach der Datei im Dateisystem". Wenn sie nicht vorhanden ist, 404 ist richtig. Dasselbe gilt, wenn er einen Dienst bittet, genau diese Datei zu liefern, und dieser Dienst ihm mitteilt, dass nichts mit diesem Namen existiert.
  • Im Fall B arbeitet der Server nicht mit "echten" Dateien, sondern die Anfrage wird von einem anderen Dienst bearbeitet - z. B. von einer Art Templating-System. In diesem Fall kann der Server keinen Anspruch auf die Existenz der Ressource erheben, da er nichts über sie weiß (es sei denn, der Dienst, der sie bearbeitet, teilt dies mit).

Ohne eine Antwort des Dienstes, die ausdrücklich ein anderes Verhalten verlangt, kann der HTTP-Server nur 3 Dinge sagen:

  • 503 wenn der Dienst, der die Anfrage bearbeiten soll, nicht läuft oder nicht antwortet;
  • 200 denn sonst kann der HTTP-Server die Anfrage tatsächlich erfüllen - egal, was der Dienst später sagt;
  • 400 o 404 um anzuzeigen, dass es keinen solchen Dienst gibt (im Gegensatz zu "existiert, ist aber offline"), und es wurde nichts anderes gefunden.

2

Um auf die eigentliche Frage zurückzukommen: Ich denke, der sauberste Ansatz wäre, überhaupt keinen HTTP-Antwortcode zu verwenden, außer dem oben genannten. Wenn der Dienst vorhanden ist und antwortet, sollte der HTTP-Code 200 sein. Die Antwort sollte den vom Dienst zurückgegebenen Status in einem separaten Header enthalten - hier kann der Dienst sagen

  • REST:EMPTY z.B. wenn er gebeten wurde, nach etw. zu suchen, und die Suche nichts ergab;
  • REST:NOT FOUND wenn er speziell nach etwas gefragt wurde. "ID-ähnlich" - sei es ein Dateiname oder eine Ressource nach ID oder Eintrag Nr. 24, etc. - und diese spezifische Ressource nicht gefunden wurde (normalerweise wurde eine spezifische Ressource angefordert und nicht gefunden);
  • REST:INVALID wenn ein Teil der gesendeten Anfrage vom Dienst nicht erkannt wird.

(Ich habe diesen Codes absichtlich "REST:" vorangestellt, um zu verdeutlichen, dass sie zwar dieselben Werte oder denselben Wortlaut wie die HTTP-Antwortcodes haben können, aber etwas völlig anderes sind)

3

Kehren wir zur obigen URL zurück und untersuchen wir den Fall B, in dem Dienstleistung zeigt dem HTTP-Server an, dass er diese Anfrage nicht selbst bearbeitet, sondern sie an SERVICE . HTTP gibt nur das aus, was es zurückerhält SERVICE weiß es nichts über den return/test Teil, der von SERVICE . Wenn dieser Dienst läuft, sollte HTTP Folgendes zurückgeben 200 da es hat tatsächlich etwas gefunden um die Anfrage zu bearbeiten.

Der Status, der von SERVICE (und die, wie gesagt, gerne in einer separaten Kopfzeile stehen würde) hängt davon ab, welche Aktion tatsächlich erwartet wird:

  • wenn return/test fragt nach einer bestimmten Ressource: Wenn sie existiert, wird sie mit dem Status REST:FOUND Wenn diese Ressource nicht existiert, wird zurückgegeben REST:NOT FOUND ; dies könnte erweitert werden, um REST:GONE wenn wir wissen, dass sie einmal existierte und nicht wiederkehren wird, und REST:MOVED wenn wir wissen, dass es hollywoodreif geworden ist
  • wenn return/test wird als such- oder filterähnliche Operation betrachtet: Wenn die Ergebnismenge leer ist, wird eine leere Menge des angeforderten Typs und ein Status von REST:EMPTY eine Reihe von Ergebnissen in der angeforderten Form und einen Status von REST:SUCCESS
  • wenn return/test ist keine Operation, die von SERVICE : zurück REST:ERROR wenn sie völlig falsch ist (z. B. ein Tippfehler wie retrun/test ), oder REST:NOT IMPLEMENTED für den Fall, dass es für später geplant ist.

4

Diese Unterscheidung ist viel sauberer als die Vermischung der beiden verschiedenen Dinge. Außerdem wird dadurch die Fehlersuche einfacher und die Verarbeitung wird, wenn überhaupt, nur geringfügig komplexer.

  • Wenn ein HTTP 404 zurückgegeben wird, sagt mir der Server: "Ich habe keine Ahnung, wovon Sie sprechen". Der REST-Teil meiner Anfrage mag zwar völlig in Ordnung sein, aber ich suche an den falschen Stellen nach par'Mach.
  • Andererseits sagt mir HTTP 200 und REST:ERR, dass ich den Dienst erhalten habe, aber bei meiner Anfrage an den Dienst etwas falsch gemacht habe.
  • Von HTTP 200 und REST:EMPTY weiß ich, dass ich nichts falsch gemacht habe - richtiger Server, der Server hat den Dienst gefunden, richtige Anfrage an den Dienst - aber das Suchergebnis ist leer.

Zusammenfassung

Das Problem und die Diskussion ergeben sich aus der Tatsache, dass HTTP-Antwortcodes verwendet werden, um den Zustand eines Dienstes zu bezeichnen, dessen Ergebnisse über HTTP bereitgestellt werden, oder um etwas zu bezeichnen, das nicht in den Bereich des HTTP-Servers selbst fällt. Aufgrund dieser Diskrepanz kann die Frage nicht beantwortet werden, und alle Meinungen sind Gegenstand zahlreicher Diskussionen.

Der Zustand einer Anfrage, die von einem Dienst und nicht vom HTTP-Server bearbeitet wurde, sollte wirklich NICHT (RFC 6919) durch einen HTTP-Antwortcode angegeben werden. Der HTTP-Code SOLLTE (RFC 2119) nur Informationen enthalten, die der HTTP-Server aus seinem eigenen Bereich heraus geben kann: nämlich, ob der Dienst gefunden wurde, um die Anfrage zu bearbeiten oder nicht.

Stattdessen SOLLTE ein anderer Weg gewählt werden, um einen Verbraucher über den Status der Anfrage an den Dienst zu informieren, der die Anfrage tatsächlich bearbeitet. Mein Vorschlag ist, dies über einen speziellen Header zu tun. Idealerweise folgen sowohl der Name der Kopfzeile als auch ihr Inhalt einem Standard, der es den Verbrauchern leicht macht, mit diesen Antworten zu arbeiten.

2voto

FishingIsLife Punkte 1599

Dies ist nur eine Ergänzung eines Entwicklers, der schon oft mit dieser Situation zu kämpfen hatte. Wie Sie vielleicht bemerkt haben, gibt es immer wieder Diskussionen darüber, ob man eine 404, 200 oder 204 zurückgibt, wenn eine bestimmte Ressource nicht existiert. Die obige Diskussion zeigt, dass dieses Thema ziemlich verwirrend und meinungsbasiert ist (obwohl es einen http-status-code Standard gibt). Ich persönlich empfehle, da es noch nicht erwähnt wurde, egal wie man sich entscheidet, DOKUMENTIEREN SIE ES IN IHRER API-DEFINITION. Natürlich hat ein Entwickler auf der Client-Seite im Sinn, wenn er/sie Ihre spezielle "REST"-API benutzt, sein/ihr Wissen über Rest zu nutzen und erwartet, dass Ihre API auf diese Weise funktioniert. Ich denke, Sie sehen die Falle. Daher verwende ich ein Readme, in dem ich explizit definiere, in welchen Fällen ich welchen Statuscode verwende. Das bedeutet nicht, dass ich irgendeine beliebige Definition verwende. Ich versuche immer, den Standard zu verwenden, aber um solche Fälle zu vermeiden, dokumentiere ich meine Verwendung. Der Kunde könnte denken, dass Sie in bestimmten Fällen falsch liegen, aber da es dokumentiert ist, gibt es keinen Grund für zusätzliche Diskussionen, was Ihnen und dem Entwickler Zeit spart.

Ein Satz zur Ops-Frage: 404 ist ein Code, der mir immer in den Sinn kommt, wenn ich daran zurückdenke, wie ich mit der Entwicklung von Backend-Anwendungen begonnen habe und ich etwas in meiner Controller-Route falsch konfiguriert habe, so dass meine Controller-Methode nicht aufgerufen wird. In diesem Sinne denke ich, wenn die Anfrage Ihren Code in einer Controller-Methode erreicht, hat der Client eine gültige Anfrage gestellt und der Anfrageendpunkt wurde gefunden. Dies ist also ein Hinweis darauf, dass 404 nicht verwendet werden sollte. Wenn die Datenbankabfrage nicht gefunden wird, gebe ich 200 zurück, aber mit einem leeren Body.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X