HTTP-Antwortcode für POST, wenn die Ressource bereits vorhanden ist

842

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)?

vmj
quelle
5
Ab Juni 2016 setzt FB offensichtlich 200 auf Registrierung, wenn E-Mail existiert
Green
4
Die Github-API gibt 422 zurück, wenn versucht wird, eine Ressource (Team / Repo) mit einem Namen zu erstellen, der bereits verwendet wird
Ken,
1
Es hängt davon ab, ob Sie die Existenz des Objekts als Fehler betrachten oder nicht. Wenn Sie das Anhängen verarbeiten, sind 200 oder 204 die am besten geeigneten Antwortcodes.
Suncat2000

Antworten:

1055

Mein Gefühl ist 409 Conflictdas am besten geeignete, aber natürlich selten in der Wildnis gesehen:

Die Anforderung konnte aufgrund eines Konflikts mit dem aktuellen Status der Ressource nicht abgeschlossen werden. Dieser Code ist nur in Situationen zulässig, in denen erwartet wird, dass der Benutzer den Konflikt möglicherweise lösen und die Anforderung erneut senden kann. Der Antworttext sollte genügend Informationen enthalten, damit der Benutzer die Ursache des Konflikts erkennen kann. Im Idealfall würde die Antwortentität genügend Informationen enthalten, damit der Benutzer oder Benutzeragent das Problem beheben kann. Dies ist jedoch möglicherweise nicht möglich und nicht erforderlich.

Konflikte treten am wahrscheinlichsten als Antwort auf eine PUT-Anforderung auf. Wenn beispielsweise die Versionierung verwendet wird und die Entität, die PUT ist, Änderungen an einer Ressource enthält, die mit denen einer früheren Anforderung (von Drittanbietern) in Konflikt stehen, verwendet der Server möglicherweise die Antwort 409, um anzuzeigen, dass die Anforderung nicht abgeschlossen werden kann . In diesem Fall würde die Antwortentität wahrscheinlich eine Liste der Unterschiede zwischen den beiden Versionen in einem Format enthalten, das durch den Antwortinhaltstyp definiert wird.

Wrikken
quelle
11
Warum nicht 400 Bad Request? Für mich sieht dies ein bisschen wie ein Validierungsfehler aus (Sie geben eine falsche Nutzlast mit einer illegalen ID an).
Manuel Aldana
314
400 => "Die Anforderung konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden" . Der Server versteht das perfekt, kann es aber aufgrund eines Konflikts nicht einhalten. An der Anfrage und Syntax ist nichts auszusetzen, nur ein Datenproblem. Ein 400 würde mich sofort glauben lassen, dass der gesamte Mechanismus, den ich verwende, fehlerhaft ist, anstatt nur die Daten.
Wrikken
42
@Wrikken Das stimmt nicht mehr. HTTP 400 wurde in RFC 7231 dahingehend geändert , dass "der Server die Anforderung aufgrund eines als Clientfehler empfundenen Fehlers (z. B. fehlerhafte Anforderungssyntax, ungültiges Anforderungsnachrichten-Framing oder irreführendes Anforderungsrouting) nicht verarbeiten kann oder wird ." Ich sage nicht, dass 400 in diesem Fall die richtige Verwendung ist, aber es könnte mit der neuen Definition von 400 richtig sein.
javajavajavajavajava
19
@javajavajavajavajava: Trotzdem sind doppelte Daten für mich kein "Client-Fehler", aber das liegt natürlich im Auge des Betrachters.
Wrikken
21
Ich kehre HTTP 409mit einem LocationHeader zurück, der auf die vorhandene / widersprüchliche Ressource verweist.
Gili
100

Gemäß RFC 7231 kann ein 303 See Other verwendet werden, wenn das Ergebnis der Verarbeitung eines POST einer Darstellung einer vorhandenen Ressource entspricht .

Nullius
quelle
4
Meiner Meinung nach könnte dies die akzeptierte Antwort sein. Obwohl "MAI" ein vollständig optionales Element anzeigt, ist dies der einzige Antwortcode, der in der offiziellen RFC 7231- Dokumentation vorgeschlagen wird.
Nando
16
Dies ist die ruhigste Antwort.
Seth
6
Ich denke, der Kontext ist wichtig. Beispiel: Wenn Sie einen 303 zurückgeben, ist eine Umleitung zur gefundenen Ressource erforderlich. Dies mag bei einem Server-zu-Server-Anruf sinnvoll sein, aber wenn Sie einen Benutzerregistrierungsprozess durchlaufen, ist dies überhaupt nicht sinnvoll.
Sinaesthetic
11
Entschuldigung, ich stimme dem zu. Bei den HTTP 300 geht es um das Umleiten, und das Umleiten zu einem anderen Objekt, das wahrscheinlich andere Eigenschaften hat, wäre sehr irreführend.
Michael Scheper
6
Du musst dich nicht entschuldigen. Wenn die Darstellung jedoch einer vorhandenen Ressource entspricht, wie kann sie unterschiedliche Eigenschaften haben? Und selbst wenn dies der Fall wäre, wie wäre eine Weiterleitung irreführend? Das OP sagt: Ich bin nicht sicher, was ich tun soll, falls das Objekt bereits vorhanden ist. Es ist in der Tat das "gleiche" Objekt. Warum sollte eine Weiterleitung irreführend sein? Sie sprechen von einem anderen Objekt, das im OP eindeutig nicht der Fall ist.
Nullius
86

Persönlich gehe ich mit der WebDAV-Erweiterung 422 Unprocessable Entity.

Gemäß RFC 4918

Der 422 Unprocessable EntityStatuscode bedeutet, dass der Server den Inhaltstyp der Anforderungsentität versteht (daher ist ein 415 Unsupported Media TypeStatuscode unangemessen) und die Syntax der Anforderungsentität korrekt ist (daher ist ein 400 Bad RequestStatuscode unangemessen), die enthaltenen Anweisungen jedoch nicht verarbeiten konnte.

Gareth
quelle
19
Dies ist ein interessanter Gedanke und hat mich dazu veranlasst, endlich den WebDAV-RFC zu lesen. Ich denke jedoch, dass die Bedeutung von 422 darin besteht, dass die Anforderung und die eingeschlossene Entität syntaktisch korrekt waren, aber semantisch keinen Sinn ergaben.
vmj
4
Malformed JSON ist keine syntaktisch korrekte Entität, daher kommt 422mir eine seltsam vor ...
awendt
7
Ich würde damit nicht gehen. Aus derselben URL, auf die in der Antwort verwiesen wird: "Diese Fehlerbedingung kann beispielsweise auftreten, wenn ein XML-Anforderungshauptteil wohlgeformte (dh syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält." Dies ist die eigentliche Bedeutung einer nicht verarbeitbaren Entität, im Gegensatz zu dem Fall, dass Sie eine vollständig gültige Anforderungsentität mit gültiger Syntax UND Semantik senden. Das einzige Problem besteht jedoch darin, dass sie mit einer vorhandenen Entität in Konflikt steht. Wenn die Semantik der Anforderungsentität nicht gültig wäre, sollte es überhaupt keine ähnliche, vorhandene Entität geben.
Tamer Shlash
1
Wenn die zweite Anfrage zuerst kam und zum Tamer-Kommentar hinzugefügt wurde, war dies erfolgreich, was nicht möglich wäre, wenn dies semantisch korrekt wäre. Daher würde in korrekter Semantik hier nicht gelten.
Harish
4
@Tamer Warum so? Der Befehl "Bitte Objekt xy erstellen" ist syntaktisch korrekt. Es ist nur dann semantisch korrekt, wenn das Objekt xy erstellt werden kann. Wenn das Objekt xy bereits vorhanden ist, kann es nicht mehr erstellt werden, daher ist dies ein semantischer Fehler.
Hagen von Eitzen
48

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:

  • 400 Bad Request - Wenn der Server eine Anfrage nicht verarbeitet, weil ein offensichtlicher Clientfehler vorliegt
  • 409 Konflikt - Wenn der Server eine Anforderung nicht verarbeitet, der Grund dafür jedoch nicht der Fehler des Clients ist
  • ...

Für implizite Handhabung von Duplikaten, Blick auf 2XX:

  • 200 OK
  • 201 Erstellt
  • ...

Wenn vom Server erwartet wird, dass er etwas zurückgibt, schauen Sie sich 3XX an:

  • 302 gefunden
  • 303 Siehe Andere
  • ...

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.

Sławomir Lenart
quelle
2
Die Anforderung dupliziert keine Ressource, sondern hängt Daten an eine an. Meiner Meinung nach ist Ihre die beste Antwort von allen.
Suncat2000
28

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 Conflictoder 403 Forbiddenabhä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 senden DELETEAnforderung, die Ressource explizit zu entfernen) oder verwenden Sie 409, wenn möglicherweise etwas getan werden könnte.

10.4.4 403 Verboten

Der Server hat die Anfrage verstanden, weigert sich jedoch, sie zu erfüllen. Die Autorisierung hilft nicht und die Anfrage sollte nicht wiederholt werden. Wenn die Anforderungsmethode nicht HEAD war und der Server veröffentlichen möchte, warum die Anforderung nicht erfüllt wurde, sollte der Grund für die Ablehnung in der Entität beschrieben werden. Wenn der Server diese Informationen dem Client nicht zur Verfügung stellen möchte, kann stattdessen der Statuscode 404 (Nicht gefunden) verwendet werden.

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 PUTvs. POST... POSTsollte 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. PUTwird verwendet, wenn die Identität der Ressource bekannt ist.

9.6 PUT

...

Der grundlegende Unterschied zwischen den POST- und PUT-Anforderungen spiegelt sich in der unterschiedlichen Bedeutung des Anforderungs-URI wider. Der URI in einer POST-Anforderung gibt die Ressource an, die die eingeschlossene Entität verarbeitet. Diese Ressource kann ein Datenakzeptanzprozess, ein Gateway zu einem anderen Protokoll oder eine separate Entität sein, die Anmerkungen akzeptiert. Im Gegensatz dazu identifiziert der URI in einer PUT-Anforderung die der Anforderung beigefügte Entität. Der Benutzeragent weiß, welcher URI beabsichtigt ist, und der Server darf NICHT versuchen, die Anforderung auf eine andere Ressource anzuwenden. Wenn der Server möchte, dass die Anforderung auf einen anderen URI angewendet wird,

es MUSS eine 301-Antwort (dauerhaft verschoben) senden; Der Benutzeragent kann dann selbst entscheiden, ob die Anforderung umgeleitet werden soll oder nicht.

p0lar_bear
quelle
7
Ich denke, 403 Verboten impliziert, dass der Benutzer, obwohl er authentifiziert ist, nicht berechtigt ist , die angeforderte Aktion auszuführen. Ich würde es nicht für Validierungsfehler verwenden. Beispiel : Nicht angemeldet, ich versuche etwas zu löschen. Der Server sendet mir 401 Unauthorized (was nur schlecht benannt ist, sollte 401 Unauthenticated sein ). Ich melde mich an und versuche es erneut. Diesmal überprüft der Server meine Berechtigungen, stellt fest, dass ich nicht zulässig bin, und gibt 403 Forbidden zurück . Siehe auch diese Frage .
Stijn de Witt
Hm ... stimmt. Der Gedanke hier war, dem Benutzer sofort mitzuteilen, dass seine Berechtigungen die Ressource im Anwendungsfall des OP unveränderlich machen. Sie ist bereits vorhanden. Sie haben keine Berechtigung, etwas zur Lösung des Konflikts zu tun. Versuchen Sie nicht, die Ressource erneut zu erstellen.
p0lar_bear
3
Gemäß der Spezifikation wird impliziert, dass der Fehler 409 nicht von einer POSTAnforderung 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 daher 409 Conflictmacht es keinen Sinn , mit zu antworten .
Grant Gryczan
1
Ich würde nicht schließen, dass ein 409-Fehler nicht von einem zurückgegeben werden kann, sondern POSTdas 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 )
JWAspin
14

"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.

Alanjds
quelle
88
3xx Status sind für die Umleitung gedacht
Aviram Netanel
1
"Die angeforderte Ressource befindet sich vorübergehend unter einem anderen URI." von w3.org/Protocols/rfc2616/rfc2616-sec10.html
Statueofmike
1
IMHO ist "307 Temporary Redirect" die echte temporäre Weiterleitung. "302" ist mehrdeutig, aber "GEFUNDEN !!" ist die wirklich gewünschte Nachricht hier. Der beste eindeutige Kompromiss ist "303 See Other" in der HTTP-Semantik. Ich würde mit "303 See Other" gehen.
Alanjds
@ DavidVartanian Hum ... Ich sehe hier keinen Fehler. Der Kunde sendet eine richtige Anfrage, aber wie sagt man "Entschuldigung, aber was Sie hier erstellen möchten, existiert bereits dort"? Scheint ein Job für einige 3xx. Es ist kein 4xx für mich, da es keinen Clientfehler gibt.
Alanjds
1
@ DavidVartanian Danke für die Diskussion. Die Antwort wurde in Richtung 409 aktualisiert . Der Kunde ist falsch, nach unmöglichen Dingen zu fragen, auch wenn er nicht weiß, dass dies unmöglich ist.
Alanjds
11

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.

Alfonso Tienda
quelle
Was ist mit einem Objekt mit einer Verknüpfungstabellenbeziehung? Angenommen, wir haben Konto, Produkt und Kontoprodukt als Datenbanktabellen. Ich möchte einem Konto ein Produkt hinzufügen, also möchte ich mit der product_id in / account / {id} / product posten. Was soll ich zurückgeben, wenn nur eine Konto-Produkt-Beziehung zulässig ist?
Partkyle
2
Vergessen Sie die Datenbanktabellen. Nehmen wir an, ein Produkt kann nur mit einem Konto verknüpft werden ... Dann ist es eine zu viele Beziehung. Also POST / product / {id} mit {'account': account_id}. Wenn Sie die maximale Kardinalität auf '1' gesetzt haben (Eins-zu-Eins-Beziehung) .... Warum sind sie getrennte Ruheobjekte? Ein Kardinalitätsfehler beträgt nur 400 Fehler. Halte es einfach. Ich hoffe ich habe deine Frage verstanden.
Alfonso Tienda
Ich habe gerade auch diese Frage gestellt und für mich ist die ID nicht die technische ID in der Datenbank, sondern so etwas wie der Buchungskreis. In dieser Anwendung kann ein Manager-Benutzer Unternehmen erstellen und muss ihnen einen Code geben. Dies ist die Firmen-ID für den Benutzer, obwohl die DB-Tabelle auch eine technische ID enthält. In meinem Fall werde ich also eine 409 zurückgeben, wenn derselbe Buchungskreis bereits vorhanden ist.
AlexCode
@partkyle Verwenden Sie keine PKs mehr als öffentliche IDs!
Sinaesthetic
Einige Entitäten haben eindeutige Einschränkungen, nicht nur die ID. Wie bei einem Konto können Sie kein Konto erstellen, wenn der Benutzer keinen Benutzernamen angibt. Und das Hinzufügen eines Kontos ohne Benutzernamen ist offensichtlich unmöglich
Rocketspacer
9

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 4xxwürde die Verwendung eines fehlerfreien Codes bedeuten, dass es sich nicht um einen Clientfehler handelt, und dies ist offensichtlich der Fall. Die Verwendung eines 4xxfehlerfreien 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 sendenPOSTWenn 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.

Grant Gryczan
quelle
422 ist eine Webdav-Spezifikation, daher würde ich nicht empfehlen, diese für eine REST-API zu verwenden
rwenz3l
7

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.) .

Sinaesthetic
quelle
Gemäß der Spezifikation wird impliziert, dass der Fehler 409 nicht von einer POSTAnforderung 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 daher 409 Conflictmacht es keinen Sinn , mit zu antworten .
Grant Gryczan
Umstritten imo. Wenn Sie an / users posten, ist die Ressource die Sammlung anstelle des einzelnen Datensatzes / users / {id}
Sinaesthetic
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."
Grant Gryczan
Ich mag Ihren Vorschlag zu verwenden PUT jedoch.
Grant Gryczan
4

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

Martin Kersten
quelle
2
Patch ist wie PUT, aber kein vollständiger Ersatz. Es wird verwendet, um einen Teil der Ressource zu ändern, z. B. ein einzelnes Element der Ressource hinzuzufügen, zu entfernen oder zu ändern, anstatt es als Ganzes zu ersetzen.
Sinaesthetic
4

Warum nicht ein 202 akzeptiert ? Es ist eine OK-Anfrage (200s), es gab per se keine Clientfehler (400s).

Aus 10 Statuscode-Definitionen :

"202 Akzeptiert. Die Anforderung wurde zur Verarbeitung angenommen, aber die Verarbeitung wurde nicht abgeschlossen."

... 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.

Phillip Harrington
quelle
21
Diese Antwort ist falsch. 202 bedeutet, dass der Server kein Problem mit der Anforderung gefunden hat, sondern die Anforderung nach der Antwort verarbeitet hat. Dies bedeutet auch, dass erwartet wird, dass die Verarbeitung erfolgreich ist. In unserem Fall weiß der Server, dass die Verarbeitung fehlschlägt, daher ist 202 die falsche Antwort.
Adrian
4
Ein Beispiel für 202 wäre eine Warteschlange oder ein Abonnement. Mit anderen Worten, das Ergebnis der Anforderung ist möglicherweise nicht sofort verfügbar, wenn Sie es sofort abfragen.
Sinaesthetic
1
Dies wäre angemessen, wenn der Server die Anforderung noch verarbeiten würde. 200 oder 204 wären häufiger. Da das OP eine Anfügeanforderung stellt, ist das Vorhandensein des Objekts eine erwartete Bedingung und kein Fehler.
Suncat2000
Es macht keinen Sinn, dem Kunden zu sagen, dass die Anfrage angenommen wurde, weil Sie bereits wissen, dass dies nicht der Fall war!
Lucastamoios
1
@Adrian und Lucastamoios Ich denke, Sie gehen beide davon aus, dass der Server synchron aus der Datenbank liest, bevor Sie die Antwort bereitstellen. Dies ist nicht immer der Fall, daher ist diese Antwort nicht "falsch", da der Server nicht immer über den vorhandenen Datensatz "Bescheid weiß". Dies ist in asynchronen Systemen sehr häufig der Fall, in denen die API-Schicht einfach die Anforderungen für die Verarbeitung durch Hintergrundarbeiter aufzeichnet.
Gsaslis
2

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

Hitin
quelle
Mein Verständnis: "Der Statuscode zeigt an, dass die Zielressource mehr als eine Darstellung hat ... Informationen zu den Alternativen werden bereitgestellt, damit der Benutzer (oder Benutzeragent) eine bevorzugte Darstellung auswählen kann, indem er seine Anforderung an eine oder mehrere dieser umleitet Bezeichner "Wir versuchen explizit, mehr als eine Darstellung zu verhindern. Es gibt keine Optionen. Es gibt keine Alternativen für den Kunden zur Auswahl. Der Client sollte erneut mit einer anderen ID einreichen. Vor diesem Hintergrund sollte auch überlegt werden, ob eindeutige IDs im Client gegenüber dem Server generiert werden sollen.
musicin3d
Semantisch sagt der Client "Create this" und der Server antwortet mit "Go here here". Das Gespräch macht keinen Sinn. Es ist fast so, als würde der Server den Client anweisen, "stattdessen an diesen Ort zu posten". 300s sind eher eine geeignetere Antwort auf eine GET-Anfrage oder einen POST, wenn der Server mit "Ok, ich habe es erstellt und es ist hier drüben" antwortet.
drüben antwortet
2

Wahrscheinlicher ist es 400 Bad Request

6.5.1. 400 schlechte Anfrage


Der Statuscode 400 (Bad Request) gibt an, dass der Server die Anforderung aufgrund eines als Clientfehler wahrgenommenen Fehlers nicht verarbeiten kann oder will (z. B. fehlerhafte Anforderungssyntax, ungültiges Anforderungsnachrichten-Framing oder irreführendes Anforderungsrouting).

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.

Mohammed Safeer
quelle
1
Eine fehlerhafte Anforderung bedeutet, dass ein inhärentes Problem mit der Syntax des Pakets vorliegt. Wenn in einem anderen Kontext (wie der Ressource, die noch nicht vorhanden ist) das Paket erfolgreich sein würde, sollte es den Fehler 400 nicht zurückgeben.
Grant Gryczan
1

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.

Fernando Ferreira
quelle
Dies ist keine Option, da Sie ein bestimmtes Element anhängen möchten, dessen ID bereits vorhanden ist. Sie versuchen also, etwas hinzuzufügen, aber das ist bereits vorhanden. Ein OK würde nur gelten, wenn der Datensatz vergrößert wurde. Etwas anhängen -> Ok, ich habe nichts angehängt. Passt nicht, denke ich.
Martin Kersten
Wie gesagt, ich glaube nicht, dass dies ein Fehler ist. Aber ich sehe den Punkt von @martin
Fernando Ferreira
Wenn die Ressource nicht erfolgreich erstellt wurde, liegt per Definition ein Fehler vor.
Grant Gryczan
POST wird auch zum Anhängen von Daten verwendet. Dies ist per Definition , nicht ein Fehler .
Suncat2000
@ Suncat2000 Auch wenn dies der Fall ist, liegt ein Fehler vor, wenn die Daten nicht erfolgreich angehängt werden. Und wenn die Ressource bereits vorhanden ist, werden keine Daten angehängt.
Grant Gryczan
0

In Ihrem Fall können Sie verwenden 409 Conflict

Und wenn Sie einen anderen überprüfen möchten HTTPs Statuscode aus der folgenden Liste

1 × x Information

100 Continue
101 Switching Protocols
102 Processing

2 × x Erfolg

200 OK
201 Created
202 Accepted
203 Non-authoritative Information
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status
208 Already Reported
226 IM Used

3 × x Umleitung

300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
308 Permanent Redirect

4 × x Client-Fehler

400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Payload Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
418 I’m a teapot
421 Misdirected Request
422 Unprocessable Entity
423 Locked
424 Failed Dependency
426 Upgrade Required
428 Precondition Required
429 Too Many Requests
431 Request Header Fields Too Large
444 Connection Closed Without Response
451 Unavailable For Legal Reasons
499 Client Closed Request

5 × x Serverfehler

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates
507 Insufficient Storage
508 Loop Detected
510 Not Extended
511 Network Authentication Required
599 Network Connect Timeout Error
Abd Abughazaleh
quelle