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
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?
Es werden zwei Fragen gestellt. Eine im Titel und eine im Beispiel. Ich denke, dies hat teilweise zu dem Streit darüber geführt, welche Antwort angemessen ist.
Im Titel der Frage wird nach leeren Daten gefragt. Leere Daten sind immer noch Daten, aber sie sind nicht dasselbe wie keine Daten. Dies legt also nahe, eine Ergebnismenge anzufordern, d. h. eine Liste, vielleicht von /users
. Wenn eine Liste leer ist, handelt es sich immer noch um eine Liste, daher ist eine 204 (ohne Inhalt) am besten geeignet. Sie haben gerade nach einer Liste von Benutzern gefragt und eine erhalten, die zufällig keinen Inhalt hat.
Das Beispiel fragt stattdessen nach einem bestimmten Objekt, einem Benutzer, /users/9
. Wenn der Benutzer #9 nicht gefunden wird, wird kein Benutzerobjekt zurückgegeben. Sie haben nach einer bestimmten Ressource (einem Benutzerobjekt) gefragt und diese nicht erhalten, weil sie nicht gefunden wurde, daher ist ein 404 angemessen.
Ich denke, die Art und Weise zu arbeiten ist, wenn Sie die Antwort in der Art und Weise, die Sie erwarten, ohne Hinzufügen einer bedingten Anweisung verwenden können, dann verwenden Sie eine 204 sonst eine 404.
In meinen Beispielen kann ich über eine leere Liste iterieren, ohne zu prüfen, ob sie Inhalt hat, aber ich kann keine Benutzerobjektdaten auf einem Null-Objekt anzeigen, ohne etwas zu brechen oder eine Prüfung hinzuzufügen, um zu sehen, ob es null ist.
Sie könnten natürlich ein Objekt mit dem Null-Objekt-Muster zurückgeben, wenn das Ihren Bedürfnissen entspricht, aber das ist eine Diskussion für ein anderes Thema.
Zusammenfassen oder vereinfachen,
2xx: Optionale Daten: Wohlgeformter URI: Kriterium ist nicht Teil des URI: Wenn das Kriterium optional ist und in @RequestBody und @RequestParam angegeben werden kann, sollte dies zu 2xx führen. Beispiel: Filter nach Name / Status
4xx: Erwartete Daten : Nicht wohlgeformter URI : Kriterium ist Teil des URI : Wenn das Kriterium obligatorisch ist und nur in @PathVariable angegeben werden kann, sollte es zu 4xx führen. Beispiel: Abfrage nach eindeutiger ID.
Also für die angefragte Situation: "users/9" würde 4xx (möglicherweise 404) sein. Aber für "users?name=superman" sollte 2xx sein (möglicherweise 204)
Was in den vorhandenen Antworten nicht näher erläutert wird, ist, dass es einen Unterschied macht, ob Sie Pfadparameter oder Abfrageparameter verwenden.
/users/9
sollte die Antwort lauten 404
weil diese Ressource nicht gefunden wurde. /users/9
ist die Ressource, und das Ergebnis ist unär oder ein Fehler, sie existiert nicht. Dies ist pas eine Monade./users?id=9
sollte die Antwort lauten 204
weil die Ressource /users
wurde gefunden, konnte aber keine Daten zurückgeben. Die Ressource /users
existiert und das Ergebnis n-är ist, existiert es auch, wenn es leer ist. Wenn id
einzigartig ist, ist diese es eine Monade.Ob Pfadparameter oder Abfrageparameter verwendet werden, hängt vom Anwendungsfall ab. Ich bevorzuge Pfadparameter für obligatorische, normative oder identifizierende Argumente und Abfrageparameter für optionale, nicht-normative oder attributive Argumente (wie Paging, Kollationierung, Gebietsschema und so weiter). In einer REST-API würde ich verwenden /users/9
pas /users?id=9
insbesondere wegen der möglichen Verschachtelung, um "untergeordnete Datensätze" zu erhalten wie /users/9/ssh-keys/0
um den ersten öffentlichen ssh-Schlüssel zu erhalten oder /users/9/address/2
um die dritte Postanschrift zu erhalten.
Ich ziehe es vor, 404 zu verwenden. Hier ist der Grund dafür:
204
ist wie ein void
Methode. Ich würde sie nicht verwenden für GET
nur für POST
, PUT
und DELETE
. Ich mache eine Ausnahme im Fall von GET
wobei die Bezeichner Abfrageparameter und nicht Pfadparameter sind.NoSuchElementException
, ArrayIndexOutOfBoundsException
oder etwas Ähnliches, weil der Client eine ID verwendet, die nicht existiert.204
bedeutet eine zusätzliche Verzweigung im Code, die vermieden werden könnte. Es verkompliziert den Client-Code und in einigen Fällen auch den Server-Code (je nachdem, ob Sie Entity/Model-Monaden oder einfache Entities/Models verwenden; und ich stark empfehlen Aufenthalt weg von Entität/Modell Monaden, es kann zu bösen Bugs führen, wo wegen der Monade Sie denken, eine Operation erfolgreich ist und 200 oder 204 zurückgeben, wenn Sie tatsächlich etwas anderes zurückgegeben haben sollte).Und nicht zuletzt: Konsistenz
GET /users/9
PUT /users/9
y DELETE /users/9
PUT /users/9
y DELETE /users/9
müssen bereits zurückkehren 204
im Falle einer erfolgreichen Aktualisierung oder Löschung. Was sollten sie also zurückgeben, wenn der Benutzer 9 nicht existiert? Es macht keinen Sinn, wenn dieselbe Situation je nach der verwendeten HTTP-Methode mit unterschiedlichen Statuscodes dargestellt wird.
Außerdem gibt es keinen normativen, sondern einen kulturellen Grund: Wenn 204
wird verwendet für GET /users/9
Das nächste, was bei dem Projekt passieren wird, ist, dass jemand denkt, dass die 204
ist gut für n-äre Methoden. Und das verkompliziert den Client-Code, denn anstatt einfach zu prüfen, ob 2xx
und die Dekodierung des Textes, muss der Client nun speziell prüfen, ob 204
und überspringen Sie in diesem Fall die Dekodierung des Körpers. Was macht der Client stattdessen? Ein leeres Array erstellen? Warum wird das dann nicht auf der Leitung übertragen? Wenn der Client das leere Array erstellt, ist 204 eine Form von dummer Kompression. Verwendet der Client null
Stattdessen wird eine ganz andere Dose Würmer geöffnet.
Según w3 Posten,
200 OK
Die Anfrage war erfolgreich. Die Informationen, die mit der Antwort zurückgegeben werden, hängen von der in der Anfrage verwendeten Methode ab
202 Angenommen
Der Antrag wurde zur Bearbeitung angenommen, aber die Bearbeitung ist noch nicht abgeschlossen.
204 Ohne Inhalt
Der Server hat die Anfrage erfüllt, muss aber keinen Entity-Body zurückgeben, sondern kann aktualisierte Metainformationen zurückgeben.
400 Schlechte Anfrage
Die Anfrage konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden. Der Client SOLLTE die Anfrage NICHT ohne Änderungen wiederholen
401 Unerlaubt
Die Anfrage erfordert eine Benutzerauthentifizierung. Die Antwort MUSS ein WWW-Authenticate-Header-Feld enthalten
404 nicht gefunden
Der Server hat nichts gefunden, was der Request-URI entspricht. Es wird nicht angegeben, ob der Zustand vorübergehend oder dauerhaft ist
Es ist traurig, dass etwas so Einfaches und gut Definiertes in diesem Thread zur "Meinungsgrundlage" wurde.
Ein HTTP-Server kennt nur "Entitäten", was eine Abstraktion für jeden Inhalt ist, sei es eine statische Webseite, eine Liste von Suchergebnissen, eine Liste von anderen Entitäten, eine json-Beschreibung von etwas, eine Mediendatei, usw. usw.
Jede solche Einheit sollte durch eine eindeutige URL identifizierbar sein, z. B.
Wenn ein Server eine Ressource unter der angegebenen URL findet, spielt es keine Rolle, was seine Inhalt are -- 2G Daten, null, {}, [] -- Solange es existiert, wird es 200 sein. Ist eine solche Entität dem Server jedoch nicht bekannt, wird ERWARTET, dass er 404 "Not Found" zurückgibt.
Eine Verwirrung scheint von Entwicklern auszugehen, die meinen, wenn die Anwendung einen Handler für eine bestimmte Pfadform hat, sollte dies kein Fehler sein. In den Augen des HTTP-Protokolls spielt es keine Rolle, was in den Interna des Servers passiert ist (d.h. ob der Standard-Router geantwortet hat oder ein Handler für eine bestimmte Pfadform), solange es auf dem Server keine passende Entität zur angeforderten URL gibt (die angeforderte MP3-Datei, Webseite, Benutzerobjekt usw.), die einen gültigen Inhalt (leer oder anders) zurückgeben würde, muss es 404 (oder 410 usw.) heißen.
Ein weiterer Punkt, der für Verwirrung sorgt, sind die Begriffe "keine Daten" und "keine Einheit". Bei ersterem geht es um den Inhalt einer Entität, bei letzterem um ihre Existenz.
Beispiel 1:
Beispiel 2:
Beispiel 3:
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.