Was ist die geeignete Antwort auf den HTTP-Statuscode für eine allgemeine erfolglose Anforderung (kein Fehler)?

107

Ich erstelle eine RESTful-API, die eine Reihe von Benutzerinteraktionen verarbeitet, einschließlich der Bestellung mit gespeicherten Kreditkarten.

Im Falle einer erfolgreichen Bestellung gebe ich ein 200 OK zurück, und in dem Fall, in dem die Bestellanforderung fehlerhaft oder ungültig ist, gebe ich eine 400 Bad Request zurück. Aber was soll ich zurückgeben, wenn bei der tatsächlichen Bearbeitung der Bestellung ein Problem auftritt?

  1. Client-POSTS-Bestellung an den Server für eine Benutzerressource. Wenn der Benutzer nicht vorhanden ist, wird 404 Not Found zurückgegeben.
  2. Bestellformat und Informationen werden validiert. Wenn nicht gültig, wird 400 Bad Request zurückgegeben.
  3. Bestellung wird bearbeitet. Wenn die Bestellung erfolgreich ist, wird ein 201 Created für die Bestellung zurückgegeben. Wenn ein unerwarteter Fehler auftritt, wird ein 500-Server-Fehler zurückgegeben.

Der letzte Schritt ist das Problem - was kann ich zurückgeben, wenn die Bestellung aus einem anderen Grund nicht abgeschlossen wird? Mögliche Szenarien könnten sein:

  • Produkt ist ausverkauft
  • Maximales Bestelllimit des Benutzers erreicht
  • Fehler bei Kreditkartentransaktionen (unzureichendes Guthaben usw.)

Dies scheint weder für eine 400 noch für eine 500 angemessen zu sein. Wenn ich keinen besseren Code finden könnte, wäre die Anfrage gemäß den Geschäftsregeln ungültig. Es scheint einfach nicht genau zu sein.

Bearbeiten: Auch diese vorhandene Diskussion zum gleichen Thema gefunden. Alle Antworten dort scheinen darauf hinzudeuten, Statuscodes für diese Art von Verletzung zu verwenden, wobei einige Diskussionen zwischen der Verwendung von 400, 409 oder der Erweiterung 422 geführt werden.

Raelshark
quelle
8
Ich mag '422 nicht verarbeitbare Entität' für Validierungsfehler. Und würde es für Ihre obigen Beispiele verwenden, eine Nachricht in die Antwort mit dem tatsächlichen Geschäftsproblem "Produkt ist ausverkauft" aufnehmen und möglicherweise Ihre eigenen "Codes" hinzufügen, wenn der Kunde programmgesteuert unterschiedliche Entscheidungen basierend auf der Antwort
treffen muss
Bevor Sie zu 422 springen, sollten Sie überlegen, ob Sie WebDAV-Funktionen unterstützen
Mbithy Mbithy

Antworten:

89

Sie sollten 400 für Geschäftsregeln verwenden. Geben Sie 2xx nicht zurück, wenn die Bestellung nicht angenommen wurde. HTTP ist ein Anwendungsprotokoll, vergessen Sie das nie. Wenn Sie 2xx zurückgeben, kann der Kunde davon ausgehen, dass die Bestellung angenommen wurde, unabhängig von den Informationen, die Sie im Text senden.


Aus dem RESTful Web Services-Kochbuch :

Ein häufiger Fehler, den einige Webdienste machen, besteht darin, einen Statuscode zurückzugeben, der den Erfolg widerspiegelt (Statuscodes von 200 bis 206 und von 300 bis 307), aber einen Nachrichtentext enthält, der einen Fehlerzustand beschreibt. Auf diese Weise wird verhindert, dass HTTP-fähige Software Fehler erkennt. Ein Cache speichert es beispielsweise als erfolgreiche Antwort und stellt es nachfolgenden Clients zur Verfügung, selbst wenn Clients möglicherweise eine erfolgreiche Anforderung stellen können.

Ich überlasse es Ihnen, zwischen 4xx und 5xx zu entscheiden, aber Sie sollten einen Fehlerstatuscode verwenden.

Max Toro
quelle
1
Haben Sie Beispiele oder Referenzen für diesen Ansatz im Vergleich zum anderen? Sowohl Ihre als auch Widors Antworten sind sinnvoll, eine aus der Sicht von HTTP als Anwendungsprotokoll und die andere, da sie ausschließlich dem Zweck der Übertragung dient. Die Spezifikation definiert es als "Protokoll auf Anwendungsebene", was etwas vage ist. Ich habe auch sowohl Perspektiven als auch Beispiele im Internet gesehen, als ich dies recherchierte.
Raelshark
Das ist so wahr.
Junge Hyun Yoo
2
Meinen Sie "Sie sollten 4xx für Geschäftsregeln verwenden"?
Yawar
28

Sie sollten 4xx für einen Clientfehler verwenden, wenn der Client die Anforderung ändern kann, um den Fehler zu umgehen. Verwenden Sie 5xx für einen Serverfehler, den der Client nicht wirklich umgehen kann.

Ausverkauftes Produkt wäre ein Serverfehler. Der Client kann die Anforderung nicht auf irgendeine Weise ändern, um den Fehler zu umgehen. Sie könnten zu einem anderen Produkt wechseln, aber wäre das nicht eine neue Anfrage?

Das maximale Bestelllimit des Benutzers ist ebenfalls ein Serverfehler. Der Client kann nichts tun, um diesen Fehler zu umgehen.

Ein Fehler bei der Kreditkartentransaktion wäre ein Clientfehler. Der Kunde kann die Anfrage mit einer anderen Zahlungsmethode oder Kreditkartennummer erneut senden, um den Fehler zu umgehen.

Paul Morgan
quelle
6
Sollte der Kunde den Benutzer nicht darauf hinweisen, wenn das Bestelllimit erreicht ist, und ihn seine Anfrage entsprechend ändern lassen? Das scheint ein 4xx Fehler zu sein. Gleiches gilt für das ausverkaufte Produkt. 5xx-Fehler sind für Fehler gedacht, die durch einen Systemausfall verursacht werden, nicht für eine Aktion, die von einer Geschäftsregel nicht zugelassen wird.
carlin.scott
7
Ich stimme dem obigen Kommentar zu. 5xx-Fehler treten auf, wenn der Server Probleme hat. 4xx Fehler für Geschäftsregeln.
Merc
21

Fehlertyp:

4×× Client Error

Fehlercode:

422 Unprocessable Entity

Der Server versteht den Inhaltstyp der Anforderungsentität (daher ist ein Statuscode für 415 nicht unterstützte Medientypen unangemessen), und die Syntax der Anforderungsentität ist korrekt (daher ist ein Statuscode für 400 fehlerhafte Anforderungen unangemessen), konnte den enthaltenen Code jedoch nicht verarbeiten Anleitung.

Diese Fehlerbedingung kann beispielsweise auftreten, wenn ein XML-Anforderungshauptteil wohlgeformte (dh syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält.

https://httpstatuses.com/422

Stamster
quelle
16

Ich weiß, dass diese Frage alt ist, aber ich habe heute dieselbe Frage gestellt. Welchen Statuscode sollte meine REST-API zurückgeben, wenn meinem Benutzer die Credits ausgehen?

Ich neige dazu 402 Payment Required:

Laut Wikipedia :

Reserviert für zukünftige Verwendung. Die ursprüngliche Absicht war, dass dieser Code als Teil eines digitalen Bargeld- oder Mikrozahlungsschemas verwendet werden könnte, aber das ist nicht geschehen, und dieser Code wird normalerweise nicht verwendet. Die Google Developers API verwendet diesen Status, wenn ein bestimmter Entwickler das tägliche Limit für Anforderungen überschritten hat.

Und tatsächlich tun sie :

PAYMENT_REQUIRED (402)

  • Ein vom Entwickler festgelegtes Tagesbudgetlimit wurde erreicht.
  • Die angeforderte Operation erfordert mehr Ressourcen, als das Kontingent zulässt. Die Zahlung ist erforderlich, um den Vorgang abzuschließen.
  • Der angeforderte Vorgang erfordert eine Zahlung vom authentifizierten Benutzer.
Benjamin
quelle
Dies ist die am besten durchdachte und logischste Antwort.
GTodorov
5

Wie wäre es 424 Failed Dependency? Die Spezifikation beschreibt es als:

Die Methode konnte nicht für die Ressource ausgeführt werden, da die angeforderte Aktion von einer anderen Aktion abhing und diese Aktion fehlschlug.

Es gibt aber auch diese Definition :

Der Statuscode 424 ist im WebDAV-Standard definiert und gilt für den Fall, dass der Client seine Aktivitäten ändern muss - der Server hat hier keine Probleme.

Sie können dem Kunden mitteilen (oder vorgeben), dass Sie interne Aktionen haben, mit denen die Bestellung erstellt und der Restbetrag abgezogen werden soll, und dass eine dieser Aktionen fehlgeschlagen ist, wenn auch aus absolut gültigen Gründen. Deshalb ist die Anforderung fehlgeschlagen.

Soweit ich sehen kann, ist "Aktion" ein ziemlich weit gefasster Begriff und kann in einer Vielzahl von Situationen verwendet werden, einschließlich unzureichender Lagerbestände, unzureichender Gutschrift oder Lagerpartynacht.


Eine andere Option könnte sein 422 Unprocessable Entity:

Der Server versteht den Inhaltstyp der Anforderungsentität (daher ist ein Statuscode für 415 nicht unterstützte Medientypen unangemessen), und die Syntax der Anforderungsentität ist korrekt (daher ist ein Statuscode für 400 fehlerhafte Anforderungen unangemessen), konnte den enthaltenen Code jedoch nicht verarbeiten Anleitung.

Diese Fehlerbedingung kann beispielsweise auftreten, wenn ein XML-Anforderungshauptteil wohlgeformte (dh syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält.

Der Versuch, einen Artikel anzufordern, der nicht vorrätig ist, oder wenn Sie nicht genügend Guthaben haben, kann auf semantischer Ebene als Fehler angesehen werden.

Mozdev sagt dies einen Fehler auf der Client - Seite zeigt, und zwar: Der Client diese Anforderung ohne Änderungen nicht wiederholen sollte.

Loopback 4 verwendet 422, wenn die Eingabevalidierung fehlschlägt.


Möglicherweise kann ein unzureichender Lagerbestand oder eine unzureichende Lagerpartynacht als vorübergehender Zustand angesehen werden, sodass die Anfrage später erneut versucht werden kann. Diese Situation kann durch angezeigt werden503 Service Unavailable

Der Server kann die Anforderung derzeit aufgrund einer vorübergehenden Überlastung oder geplanten Wartung nicht verarbeiten, was wahrscheinlich nach einer gewissen Verzögerung behoben wird.

Der Server kann ein Retry-After-Header-Feld senden, um dem Client eine angemessene Wartezeit vor dem erneuten Versuch der Anforderung vorzuschlagen.

joeytwiddle
quelle
Keine davon bezieht sich auf eine Zahlung. Ich gehe mit 402 aus der vorherigen Antwort!
GTodorov
2

Ich glaube nicht, dass 400 für alle Geschäftsszenarien verwendet werden kann. Es kann für die grundlegende Validierung der Dateneingabe verwendet werden. Darüber hinaus fällt es uns möglicherweise schwer, andere Geschäftslogiken in diesen Fehlercode einzupassen. Die dabei behandelten Fehler sind meistens Entwurfszeitfehler, auf die Entwickler möglicherweise während der Codierung des Clients stoßen.

Angenommen, alle Parameter sind korrekt, und wir geben die Benutzerkontonummer an die Anforderung weiter.

Damit die Anfrage jetzt keine schlechte Anfrage mehr ist, kann der Server die Anfrage annehmen. Aber jetzt weigert es sich, die Anfrage auf der Grundlage neuer verfügbarer Informationen zu erfüllen, nämlich - das Konto verfügt nicht über ein ausreichendes Guthaben.

Ich würde vorschlagen, dass wir in diesen Szenarien 403 mit der entsprechenden Fehlermeldung verwenden sollten.

Ein anderer möglicher Fehlercode könnte ein Konflikt sein. Dies wird jedoch in Szenarien verwendet, in denen sich die Ressource in einem konsistenten Zustand befindet.

Rajender Saini
quelle
-1

Ich gehe mit 406 Not Acceptable.

Hier ist eine 4xx Liste:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585
Mahmoud Zalt
quelle
8
Während der Name des Statuscodes 406 für sich genommen genau klingt, müssen Sie sich bewusst sein, dass jeder Statuscode eine maßgebliche Textbeschreibung enthält. Die Beschreibung für den Statuscode 406 ist für den vorliegenden Fall nicht geeignet . Siehe zum Beispiel httpstatuses.com/406 .
Zero3
1
@ Zero3 ist richtig, dieser Code bedeutet, dass der Antworttyp nicht akzeptabel ist, da zwischen den vom Client gesendeten Accept-Headern und den vom Endpunkt gesendeten Medientypen, z. B. application / json vs. text / plain
Gregor, eine Nichtübereinstimmung besteht