Ich baue einen Server, auf dem Clients Objekte speichern können. Diese Objekte werden auf Client-Seite vollständig erstellt und enthalten Objekt-IDs, die für die gesamte Lebensdauer des Objekts dauerhaft sind.
Ich habe die API so definiert, dass Clients Objekte mit PUT erstellen oder ändern können:
PUT /objects/{id} HTTP/1.1
...
{json representation of the object}
Die {id} ist die Objekt-ID und daher Teil des Request-URI.
Jetzt denke ich auch darüber nach, Clients zu erlauben, das Objekt mit POST zu erstellen:
POST /objects/ HTTP/1.1
...
{json representation of the object, including ID}
Da POST als "Anhängen" -Operation gedacht ist, bin ich mir nicht sicher, was ich tun soll, falls das Objekt bereits vorhanden ist. Sollte ich die Anfrage als Änderungsanforderung behandeln oder einen Fehlercode zurückgeben (welcher)?
Antworten:
Mein Gefühl ist
409 Conflict
das am besten geeignete, aber natürlich selten in der Wildnis gesehen:quelle
HTTP 409
mit einemLocation
Header zurück, der auf die vorhandene / widersprüchliche Ressource verweist.Gemäß RFC 7231 kann ein 303 See Other verwendet werden, wenn das Ergebnis der Verarbeitung eines POST einer Darstellung einer vorhandenen Ressource entspricht .
quelle
Persönlich gehe ich mit der WebDAV-Erweiterung
422 Unprocessable Entity
.Gemäß RFC 4918
quelle
422
mir eine seltsam vor ...Es geht nur um den Kontext und auch darum , wer für die Verarbeitung von Duplikaten in Anforderungen verantwortlich ist (Server oder Client oder beides).
Wenn der Server nur auf das Duplikat zeigt , sehen Sie sich 4xx an:
Für implizite Handhabung von Duplikaten, Blick auf 2XX:
Wenn vom Server erwartet wird, dass er etwas zurückgibt, schauen Sie sich 3XX an:
Wenn der Server auf die vorhandene Ressource verweisen kann, bedeutet dies eine Umleitung.
Wenn dies nicht ausreicht, empfiehlt es sich immer, eine Fehlermeldung im Hauptteil der Antwort vorzubereiten.
quelle
Vielleicht zu spät zum Spiel, aber ich bin auf dieses Semantikproblem gestoßen, als ich versucht habe, eine REST-API zu erstellen.
Um Wrikkens Antwort ein wenig zu erweitern, können Sie entweder
409 Conflict
oder403 Forbidden
abhängig von der Situation verwenden. Kurz gesagt, verwenden Sie einen 403-Fehler, wenn der Benutzer absolut nichts tun kann, um den Konflikt zu lösen und die Anforderung abzuschließen (z. B. kann er keine sendenDELETE
Anforderung, die Ressource explizit zu entfernen) oder verwenden Sie 409, wenn möglicherweise etwas getan werden könnte.Heutzutage sagt jemand "403" und ein Berechtigungs- oder Authentifizierungsproblem kommt in den Sinn, aber die Spezifikation besagt, dass es im Grunde der Server ist, der dem Client sagt, dass er es nicht tun wird, fragen Sie es nicht noch einmal, und hier ist, warum der Client es nicht tun sollte 't.
Wie für
PUT
vs.POST
...POST
sollte verwendet werden, um eine neue Instanz einer Ressource zu erstellen, wenn der Benutzer keine Möglichkeit hat oder keine Kennung für die Ressource erstellen sollte.PUT
wird verwendet, wenn die Identität der Ressource bekannt ist.quelle
POST
Anforderung zurückgegeben werden kann (wenn er korrekt verwendet wird), da er angibt, dass er zurückgegeben werden soll, wenn er mit der Zielressource in Konflikt steht . Da die Zielressource noch nicht veröffentlicht wurde, kann es unmöglich zu Konflikten kommen, und daher409 Conflict
macht es keinen Sinn , mit zu antworten .POST
das Gegenteil, weil "Konflikte am wahrscheinlichsten als Antwort auf eine PUT-Anfrage auftreten". scheint darauf hinzudeuten, dass auch andere Anforderungsmethoden diesen Code verwenden können. Außerdem : „Die Antwort Körper sollte genug Informationen enthalten , dass der Benutzer die Quelle des Konflikts zu erkennen Idealerweise würde die Antwort Unternehmen genügend Informationen für den Benutzer oder Benutzerprogramm enthalten , das Problem zu beheben,. Jedoch, dass nicht möglich sein könnte , und ist nicht erforderlich . " ( webdav.org/specs/rfc2616.html#status.409 )"302 gefunden" klingt für mich logisch. Und der RFC 2616 sagt, dass er für andere Anfragen als GET und HEAD beantwortet werden kann (und dies schließt sicherlich POST ein).
Der Besucher wird jedoch weiterhin auf diese URL zugreifen, um diese "Gefundene" Ressource vom RFC abzurufen. Um direkt zur echten "Gefundenen" URL zu gelangen, sollte "303 See Other" verwendet werden. Dies ist sinnvoll, erzwingt jedoch einen weiteren Aufruf, um die folgende URL abzurufen. Auf der guten Seite ist dieses GET zwischenspeicherbar.
Ich denke, dass ich "303 See Other" verwenden würde . Ich weiß nicht, ob ich mit dem "Ding" im Körper antworten kann, aber ich möchte dies tun, um eine Hin- und Rückfahrt auf dem Server zu speichern.
UPDATE: Nach dem erneuten Lesen des RFC denke ich immer noch, dass ein nicht vorhandener "4XX + 303 Found" -Code der richtige sein sollte. Der "409-Konflikt" ist jedoch der beste vorhandene Antwortcode (wie von @Wrikken angegeben), möglicherweise mit einem Standortheader, der auf die vorhandene Ressource verweist.
quelle
Ich denke nicht, dass du das tun solltest.
Wie Sie wissen, dient der POST zum Ändern der Sammlung und zum Erstellen eines neuen Elements. Wenn Sie also die ID senden (ich denke, das ist keine gute Idee), sollten Sie die Sammlung ändern, dh das Element ändern, aber es ist verwirrend.
Verwenden Sie diese Option, um ein Element ohne ID hinzuzufügen. Es ist die beste Praxis.
Wenn Sie eine EINZIGARTIGE Einschränkung (nicht die ID) erfassen möchten, können Sie wie bei PUT-Anforderungen auf 409 antworten. Aber nicht die ID.
quelle
Ich würde mit gehen
422 Unprocessable Entity
, was verwendet wird, wenn eine Anfrage ungültig ist, aber das Problem nicht in der Syntax oder Authentifizierung liegt.Als Argument gegen andere Antworten
4xx
würde die Verwendung eines fehlerfreien Codes bedeuten, dass es sich nicht um einen Clientfehler handelt, und dies ist offensichtlich der Fall. Die Verwendung eines4xx
fehlerfreien Codes zur Darstellung eines Clientfehlers macht überhaupt keinen Sinn.Es scheint, dass
409 Conflict
hier die häufigste Antwort ist, aber gemäß der Spezifikation impliziert dies, dass die Ressource bereits vorhanden ist und die neuen Daten, die Sie auf sie anwenden, nicht mit ihrem aktuellen Status kompatibel sind. Wenn Sie eine sendenPOST
Wenn Sie beispielsweise einen Benutzernamen verwenden, der bereits vergeben ist, besteht kein Konflikt mit der Zielressource, da die Zielressource (die Ressource, die Sie erstellen möchten) noch nicht veröffentlicht wurde. Dies ist ein Fehler speziell für die Versionskontrolle, wenn ein Konflikt zwischen der Version der gespeicherten Ressource und der Version der angeforderten Ressource besteht. Dies ist zu diesem Zweck sehr nützlich, beispielsweise wenn der Client eine alte Version der Ressource zwischengespeichert hat und eine Anforderung basierend auf dieser falschen Version sendet, die nicht mehr bedingt gültig wäre. "In diesem Fall würde die Antwortdarstellung wahrscheinlich Informationen enthalten, die zum Zusammenführen der Unterschiede basierend auf dem Revisionsverlauf nützlich sind." Die Anforderung, einen anderen Benutzer mit diesem Benutzernamen zu erstellen, ist einfach nicht verarbeitbar und hat nichts mit der Versionskontrolle zu tun.Für den Datensatz ist 422 auch der Statuscode, den GitHub verwendet, wenn Sie versuchen, ein Repository mit einem bereits verwendeten Namen zu erstellen.
quelle
Ich denke, für REST müssen Sie nur eine Entscheidung über das Verhalten für dieses bestimmte System treffen. In diesem Fall wäre die "richtige" Antwort eine von mehreren hier gegebenen Antworten. Wenn Sie möchten, dass die Anforderung gestoppt wird und sich so verhält, als ob der Client einen Fehler gemacht hat, den er beheben muss, bevor Sie fortfahren, verwenden Sie 409. Wenn der Konflikt wirklich nicht so wichtig ist und Sie die Anforderung am Laufen halten möchten, leiten Sie die Antwort um Client für die gefundene Entität. Ich denke, richtige REST-APIs sollten ohnehin nach einem POST zum GET-Endpunkt für diese Ressource umleiten (oder zumindest den Standortheader bereitstellen), damit dieses Verhalten eine konsistente Erfahrung ergibt.
BEARBEITEN: Es ist auch erwähnenswert, dass Sie einen PUT in Betracht ziehen sollten, da Sie die ID angeben. Dann ist das Verhalten einfach: "Es ist mir egal, was gerade da ist, leg das Ding dort hin." Das heißt, wenn nichts da ist, wird es geschaffen; Wenn etwas da ist, wird es ersetzt. Ich denke, ein POST ist besser geeignet, wenn der Server diese ID verwaltet. Wenn Sie die beiden Konzepte trennen, erfahren Sie im Grunde, wie Sie damit umgehen sollen (dh PUT ist idempotent und sollte immer funktionieren, solange die Nutzdaten validiert werden. POST erstellt immer. Wenn also eine Kollision von IDs vorliegt, würde ein 409 diesen Konflikt beschreiben.) .
quelle
POST
Anforderung zurückgegeben werden kann (wenn er korrekt verwendet wird), da er angibt, dass er zurückgegeben werden soll, wenn er mit der Zielressource in Konflikt steht . Da die Zielressource noch nicht gebucht wurde, kann es unmöglich zu Konflikten kommen, und daher409 Conflict
macht es keinen Sinn , mit zu antworten .PUT
jedoch.Eine weitere mögliche Behandlung ist schließlich die Verwendung von PATCH. Ein PATCH ist definiert als etwas, das den internen Status ändert und nicht auf das Anhängen beschränkt ist.
PATCH würde das Problem lösen, indem Sie bereits vorhandene Elemente aktualisieren können. Siehe: RFC 5789: PATCH
quelle
Warum nicht ein 202 akzeptiert ? Es ist eine OK-Anfrage (200s), es gab per se keine Clientfehler (400s).
Aus 10 Statuscode-Definitionen :
... weil es nicht fertiggestellt werden musste, weil es bereits existierte. Der Kunde weiß nicht, dass es bereits existiert, er hat nichts falsch gemacht.
Ich lehne mich daran, eine 202 zu werfen und ähnliche Inhalte zurückzugeben, die ein GET zurückgegeben
/{resource}/{id}
hätte.quelle
Stolperte über diese Frage, während ich nach korrektem Code für doppelte Datensätze suchte.
Verzeihen Sie meine Unwissenheit, aber ich verstehe nicht, warum jeder den Code "300" ignoriert, der eindeutig "Multiple Choice" oder "Ambiguous" sagt.
Meiner Meinung nach wäre dies der perfekte Code zum Erstellen eines nicht standardmäßigen oder eines bestimmten Systems für Ihren eigenen Gebrauch. Ich könnte mich auch irren!
https://tools.ietf.org/html/rfc7231#section-6.4.1
quelle
Wahrscheinlicher ist es
400 Bad Request
Da die Anforderung einen doppelten Wert enthält (Wert, der bereits vorhanden ist), kann sie als Clientfehler wahrgenommen werden. Sie müssen die Anforderung vor dem nächsten Versuch ändern.
Unter Berücksichtigung dieser Tatsachen können wir als HTTP STATUS 400 Bad Request schließen.
quelle
Was ist mit 208 - http://httpstatusdogs.com/208-already-reported ? Ist das eine Option?
Meiner Meinung nach sollte kein Fehler ausgelöst werden, wenn das einzige eine Wiederholungsressource ist. Schließlich gibt es weder auf der Client- noch auf der Serverseite einen Fehler.
quelle
In Ihrem Fall können Sie verwenden
409 Conflict
Und wenn Sie einen anderen überprüfen möchten
HTTPs
Statuscode aus der folgenden Liste1 × x Information
2 × x Erfolg
3 × x Umleitung
4 × x Client-Fehler
5 × x Serverfehler
quelle