it-swarm.com.de

REST HTTP-Statuscodes für fehlgeschlagene Validierung oder ungültiges Duplikat

Ich erstelle eine Anwendung mit einer REST-basierten API und bin an dem Punkt angelangt, an dem ich Statuscodes für jede Anforderung spezifiziere.

Welchen Statuscode soll ich für Anfragen senden, deren Validierung fehlgeschlagen ist oder bei denen eine Anfrage versucht, ein Duplikat in meine Datenbank aufzunehmen?

Ich habe durchgesehen http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html aber keiner von ihnen scheint richtig zu sein.

Gibt es eine übliche Vorgehensweise beim Senden von Statuscodes?

761
alexn

Bei fehlgeschlagener Eingabevalidierung: 400 Bad Request + Ihre optionale Beschreibung. Dies wird im Buch " RESTful Web Services " vorgeschlagen. Für Doppeleinreichung: 409 Conflict


Update Juni 2014

Die relevante Spezifikation war RFC2616 , was die Verwendung von 400 (Bad Request) ziemlich eng machte

Die Anforderung konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden

Es könnte also argumentiert worden sein, dass es für semantische Fehler ungeeignet ist. Aber nicht mehr; seit Juni 2014 gibt der relevante Standard RFC 7231 , der den vorherigen RFC2616 ersetzt, die Verwendung von 400 (Bad Request) weiter als

der Server kann oder wird die Anforderung aufgrund eines als Clientfehler wahrgenommenen Problems nicht verarbeiten

730
deamon
  • Validierung fehlgeschlagen: 403 Verboten ("Der Server hat die Anforderung verstanden, sie jedoch nicht erfüllt"). Entgegen der landläufigen Meinung sagt RFC2616 nicht "403 ist nur für fehlgeschlagene Authentifizierung gedacht", sondern "403: Ich weiß, was Sie wollen, aber ich werde das nicht tun". Diese Bedingung kann auf eine Authentifizierung zurückzuführen sein oder nicht.
  • Es wurde versucht, ein Duplikat hinzuzufügen: 409 Konflikt ("Die Anforderung konnte aufgrund eines Konflikts mit dem aktuellen Status der Ressource nicht ausgeführt werden.")

Sie sollten auf jeden Fall eine detailliertere Erklärung in den Antwort-Headern und/oder im Body angeben (z. B. mit einem benutzerdefinierten Header - X-Status-Reason: Validation failed).

270
Piskvor

Ich empfehle Statuscode 422, "Unprocessable Entity" .

11.2. 422 Nicht verarbeitbare Einheit

Der Statuscode 422 (Nicht verarbeitbare Entität) bedeutet, dass der Server den Inhaltstyp der Anforderungsentität versteht (daher ist ein Statuscode 415 (Nicht unterstützter Medientyp) ungeeignet) und die Syntax der Anforderungsentität korrekt ist (daher eine 400 (ungültige Anforderung) ) Der Statuscode ist unangemessen.) Die enthaltenen Anweisungen konnten jedoch nicht verarbeitet werden. Diese Fehlerbedingung kann beispielsweise auftreten, wenn ein XML-Anforderungstext wohlgeformte (d. H. Syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält.

192
Julian Reschke

200.300, 400, 500 sind alle sehr allgemein. Wenn Sie generisch möchten, ist 400 OK.

422 wird von einer zunehmenden Anzahl von APIs verwendet und wird sogar von Rails "out of the box" verwendet.

Unabhängig davon, welchen Statuscode Sie für Ihre API auswählen, wird jemand anderer Meinung sein. Aber ich bevorzuge 422, weil ich 400 + Textstatus als zu generisch betrachte. Außerdem nutzen Sie keinen JSON-fähigen Parser. Im Gegensatz dazu ist ein 422 mit einer JSON-Antwort sehr explizit und es können viele Fehlerinformationen übermittelt werden.

Apropos JSON-Antwort: Ich neige dazu, die Rails -Fehlerantwort für diesen Fall zu standardisieren:

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

Dieses Format eignet sich perfekt für die Formularvalidierung. Ich halte dies für den komplexesten Fall in Bezug auf die Fehlerberichterstattung. Wenn dies Ihre Fehlerstruktur ist, wird sie wahrscheinlich alle Ihre Anforderungen an die Fehlerberichterstattung erfüllen.

76
sethcall

Ein Duplikat in der Datenbank sollte ein 409 CONFLICT sein.

Ich empfehle 422 UNPROCESSABLE ENTITY für Validierungsfehler.

Ich erkläre hier 4xx-Codes ausführlicher: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/

38
Phil Parker

200

Ugh ... (309, 400, 403, 409, 415, 422) ... viele Antworten, die versuchen, den besten Rückkehrcode für eine erfolgreiche HTTP-Anfrage zu erraten, zu argumentieren und zu standardisieren aber ein fehlgeschlagener REST Aufruf .

Es ist falsch , HTTP-Statuscodes und REST-Statuscodes zu mischen.

Ich habe jedoch viele Implementierungen gesehen, die sich mischten, und viele Entwickler stimmen mir möglicherweise nicht zu.

HTTP-Rückkehrcodes beziehen sich auf den HTTP Request selbst. Ein REST -Aufruf wird unter Verwendung einer Hypertext Transfer Protocol-Anforderung ausgeführt und funktioniert auf einer niedrigeren Ebene als die aufgerufene REST -Methode. REST ist ein Konzept/Ansatz und seine Ausgabe ist ein geschäftliches/logisches Ergebnis, während der HTTP-Ergebniscode ein Transport ist einer.

Wenn Sie beispielsweise/users/aufrufen, ist die Rückgabe von 404 Not found verwirrend, da dies Folgendes bedeuten kann:

  • URI ist falsch (HTTP)
  • Es wurden keine Benutzer gefunden (REST)

"403 Verboten/Zugriff verweigert" kann bedeuten:

  • Sondergenehmigung erforderlich. Browser können damit umgehen, indem sie nach dem Benutzer/Passwort fragen. (HTTP)
  • Falsche Zugriffsberechtigungen auf dem Server konfiguriert. (HTTP)
  • Sie müssen authentifiziert sein (REST)

Und die Liste kann mit "500 Server error" (ein Apache/Nginx-HTTP-Fehler oder ein Business-Constraint-Fehler in REST) ​​oder anderen HTTP-Fehlern usw. fortgesetzt werden.

Aus dem Code ist schwer zu verstehen, was der Grund für den Fehler war, ein HTTP-Fehler (Transportfehler) oder ein REST-Fehler (logischer Fehler).

Wenn die HTTP-Anforderung physisch erfolgreich ausgeführt wurde, sollte immer 200-Code zurückgeben, unabhängig davon, ob die Datensätze gefunden wurden oder nicht. Weil die URI-Ressource gefunden wurde und vom HTTP-Server verarbeitet wurde. Ja, möglicherweise wird ein leerer Satz zurückgegeben. Ist es möglich, eine leere Webseite mit 200 als HTTP-Ergebnis zu erhalten, oder?

Stattdessen können Sie 200 HTTP-Code mit einigen Optionen zurückgeben:

  • Das Objekt "error" in JSON führt dazu, dass ein Fehler auftritt
  • Leeres JSON-Array/-Objekt, wenn kein Datensatz gefunden wurde
  • Ein bool result/success Flag in Kombination mit vorherigen Optionen für eine bessere Handhabung.

Außerdem können einige Internetanbieter Ihre Anforderungen abfangen und Ihnen einen 404-HTTP-Code zurückgeben. Dies bedeutet nicht, dass Ihre Daten nicht gefunden werden, aber auf Transportebene stimmt etwas nicht.

Von Wiki :

Im Juli 2004 stellte der britische Telekommunikationsanbieter BT Group das System zur Blockierung von Cleanfeed-Inhalten bereit, das eine 404-Fehlermeldung für alle von der Internet Watch Foundation als potenziell illegal erkannten Anforderungen an Inhalte zurückgibt. Andere ISPs geben unter denselben Umständen einen "verbotenen" HTTP 403-Fehler zurück. Auch in Thailand und Tunesien wurde über die Praxis berichtet, gefälschte 404-Fehler zu verwenden, um die Zensur zu verschleiern. In Tunesien, wo die Zensur vor der Revolution von 2011 schwerwiegend war, wurden die Menschen auf die Natur der gefälschten 404-Fehler aufmerksam und schufen eine imaginäre Figur namens "Ammar 404", die "den unsichtbaren Zensor" darstellt.

Warum antworten Sie nicht einfach mit so etwas?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

Google gibt in der Geocoding-API immer 200 als Statuscode zurück, auch wenn die Anforderung logisch fehlschlägt: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

Facebook gibt bei erfolgreichen HTTP-Anfragen immer 200 zurück, auch wenn die Anfrage mit REST fehlschlägt: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling)

Es ist ganz einfach, HTTP-Statuscodes gelten für HTTP-Anforderungen. REST API ist Ihre, definieren Sie Ihre Statuscodes.

26
Marcodor

Der ActiveRecord-Adapter von Ember-Data erwartet, dass 422 UNPROCESSABLE ENTITY vom Server zurückgegeben wird. Wenn Ihr Client in Ember.js geschrieben ist, sollten Sie 422 verwenden. Nur dann werden DS.Errors mit zurückgegebenen Fehlern gefüllt. Sie können natürlich 422 in einen anderen Code ändern in Ihrem Adapter.

7
Daniel Kmak

Statuscode 304 nicht geändert würde auch eine akzeptable Antwort auf eine doppelte Anforderung geben. Dies ähnelt der Verarbeitung eines Headers von If-None-Match mit einem Entity-Tag.

Meiner Meinung nach ist die Antwort von @ Piskvor die naheliegendere Wahl für das, was ich für die Absicht der ursprünglichen Frage halte, aber ich habe eine Alternative, die auch relevant ist.

Wenn Sie eine doppelte Anforderung als Warnung oder Benachrichtigung und nicht als Fehler behandeln möchten, sind der Antwortstatuscode 304 Nicht geändert und der Header Content-Location, der die vorhandene Ressource identifiziert, genauso gültig. Wenn lediglich sichergestellt werden soll, dass eine Ressource vorhanden ist, ist eine doppelte Anforderung kein Fehler, sondern eine Bestätigung. Die Anforderung ist nicht falsch, sondern einfach redundant, und der Client kann auf die vorhandene Ressource verweisen.

Mit anderen Worten, die Anforderung ist in Ordnung, aber da die Ressource bereits vorhanden ist, muss der Server keine weitere Verarbeitung durchführen.

6
Suncat2000