Angenommen, ich habe einen REST-Endpunkt, der eine Ganzzahl als Parameter verwendet:
/makeWaffles?numberOfWaffles=3
In diesem Fall möchte ich, dass die Zahl positiv ist, da ich keine negative Anzahl von Waffeln herstellen kann (und das Anfordern von 0 Waffeln ist Zeitverschwendung). Ich möchte also jede Anfrage ablehnen, die keine positive Ganzzahl enthält. Ich möchte auch eine Anfrage ablehnen, die eine maximale Ganzzahl überschreitet (sagen wir mal, es ist MAX_INTEGER).
Soll ich für den Fall, dass jemand eine nicht positive Anzahl von Waffeln anfordert, einen HTTP 400-Status (Bad Request) zurückgeben? Mein erster Gedanke ist ja: Es ist keine gültige Nummer für mich, um die Anfrage abzuschließen. Der RFC nennt jedoch keine Geschäftsregeln als Grund, es zu werfen:
Der Statuscode 400 (Bad Request) gibt an, dass der Server die Anforderung aufgrund eines als Clientfehler wahrgenommenen Problems (z. B. fehlerhafte Anforderungssyntax, ungültige Anforderungsnachrichten oder irreführendes Anforderungsrouting) nicht verarbeiten kann oder wird.
Eine Geschäftsregel fällt nicht unter eines dieser drei Beispiele. Es ist syntaktisch korrekt, richtig eingerahmt und täuscht nicht über das Weiterleiten von Anforderungen.
Soll ich also einen HTTP 400-Status (Bad Request) zurückgeben, wenn ein Parameter syntaktisch korrekt ist, aber eine Geschäftsregel verletzt? Oder gibt es einen angemesseneren Status für die Rückgabe?
quelle
Antworten:
Dies ist eine große Frage, die angesichts des historischen Kontexts (und der scheinbar widersprüchlichen Definitionen) der HTTP-Rückkehrcodes immer noch von hoher Relevanz ist. Auch bei den Antworten auf diese Frage gibt es widersprüchliche Definitionen. Dies kann durch chronologische Bewegung geklärt werden.
RFC 2616 (Juni 1999)
Ab diesem RFC galt dieser Statuscode speziell nur für syntaktisch ungültige Anforderungen. Es gab eine Lücke in den Statuscodes für die semantische Validierung. Als RFC 4918 auf den Markt kam, entstand ein neuer Code.
RFC 4918 (Juni 2007)
422 Unprocessable Entity wurde erstellt, um die Lücke der semantischen Validierung in der ursprünglichen Spezifikation der 4xx-Statuscodes zu schließen. 2014 kam jedoch ein weiterer relevanter RFC hinzu, in dem 400 nicht mehr syntaxspezifisch verallgemeinert wurden .
RFC 7231 (Juni 2014, RFC 2616 explizit veraltet)
Beachten Sie, dass die 422-Beschreibung besagt, dass der Grund für die Unangemessenheit von 400 darin besteht, dass 400 (ab RFC 2616) nur für eine falsche Anforderungssyntax zurückgegeben werden sollte. Doch wie von RFC 7231, die strengen Syntax-Fehlerdefinition nicht mehr auf 400 .
Zurück zur vorliegenden Frage: Während 422 in diesem Zusammenhang technisch spezifischer ist, konnte ich sehen, dass entweder 400 oder 422 für die semantische Validierung von API-Parametern verwendet werden. Ich zögere, 422 in meinen eigenen APIs zu verwenden, da die Definition von 422 zu diesem Zeitpunkt technisch veraltet ist (obwohl ich nicht weiß, ob dies offiziell irgendwo anerkannt ist). Der Artikel, auf den in Frans Antwort verwiesen wird, die die Verwendung von 422 fördert, wurde 2012 geschrieben, zwei Jahre bevor RFC 7231 HTTP 400 klarstellte.
quelle
Ich habe die erste Antwort gelesen und war nicht wirklich damit einverstanden, weil eine schlechte Anfrage (400) zumindest in meiner Lektüre bedeutet: "Ich kann Ihre Anfrage nicht einmal bearbeiten, weil etwas grundlegend falsch ist." Und ich habe diesen Beitrag gefunden, der die Rückgabe eines 422 rechtfertigt.
von IETF
422 Unprocessable Entity (WebDAV; RFC 4918) Die Anforderung war ordnungsgemäß aufgebaut, konnte jedoch aufgrund semantischer Fehler nicht befolgt werden
Dies scheint eine angemessenere Antwort zu sein, da Ihre Anfrage wohlgeformt ist, aber Ihre Validierungsregeln nicht erfüllt.
quelle
Ja, Eingaben, die nicht dem implizierten Vertrag des Endpunkts entsprechen, sind "als Clientfehler wahrgenommen" und sollten 400 zurückgeben.
Die Ausnahme ist, wenn die Geschäftsregel sicherheitsrelevant ist (dann
401 Unauthorized
oder403 Forbidden
besser wäre). Alternativ, wenn das Senden einer 400 Informationen über die Existenz von etwas verlieren würde, ist eine404 Not Found
möglicherweise geeigneter.quelle
Nein, das solltest du nicht. HTTP-Codes sind für die HTTP-Schicht Ihrer Anwendung bestimmt. Geschäftsregeln sind eine völlig andere Ebene und anwendungsspezifisch. Sie müssen daher ein eigenes "Protokoll" erstellen.
Stellen Sie sich eine Apokalypse vor und Sie müssen vom HTTP-Protokoll zur Verwendung von Pigeons wechseln. Tauben haben keine Rückkehrcodes, daher müssten Sie Ihre Geschäftsschicht ändern, um dem Rechnung zu tragen. Ihr Unternehmen hat sich jedoch nicht wirklich verändert, sodass Sie die Business-Schicht nicht ändern müssen. Es zeigt eine enge Kopplung zwischen diesen beiden Schichten (Transport und Geschäft).
Zurück zur Frage: Geben Sie "200 OK" mit einem Text zurück, der beschreibt, was mit der Anforderung geschehen ist. In der Spezifikation heißt es eindeutig:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .
War Ihre HTTP-Anfrage erfolgreich? Ja, der Webserver weiß, wie er mit dieser Anforderung umgehen soll (z. B. an den Serverteil Ihrer Anwendung weiterleiten). Der Webserver leitet diese Anforderung dann an den Serverteil Ihrer Anwendung weiter, der die POST-Daten verarbeitet (in Ihrem Fall validiert) und eine normale Antwort (im Hauptteil einer HTTP-Antwort) an den Client-Teil Ihrer Anwendung zurückgibt . Diese Antwort vom Serverteil der Anwendung kann entweder "Großartig, die von Ihnen gesendeten Daten sind gültig" oder "Es tut mir leid, die von Ihnen gesendeten Daten sind ungültig" sein. Und es liegt an Ihrem Kunden, zu verstehen, was die Antwort bedeutet.
PS: "400 Bad Request" bedeutet, dass der Webserver nicht verstanden hat, was Sie von ihm wollen. Dies bedeutet, dass Ihr Serverteil Ihrer Anwendung die Anfrage nicht einmal erhalten hat. Zumindest ist das so gemeint :-)
EDIT : Mir ist gerade aufgefallen, dass Sie eine GET-Anfrage machen, nicht POST. Dies ist eine schlechte Idee, da GET den Status der Anwendung nicht ändern sollte. GET soll einfach Daten vom Server abrufen. Aber in Ihrer Anfrage ändern Sie tatsächlich den Status der Anwendung, sodass Sie POST wirklich verwenden sollten.
quelle
Ich bin mir nicht sicher, ob alle zustimmen würden, aber wir verwenden 409 - Conflict. Viele geben an, dass der 409 eher ein Konflikt mit dem Systemstatus ist, aber wir haben die Interpretation akzeptiert, dass ein Konflikt von Datenwerten, die außerhalb des akzeptierten Bereichs liegen, vom Anforderer behoben werden kann, und eine akzeptable Verwendung von 409. 422 Ich halte dies für angemessen ist korrekt aufgebaut, kann aber nicht wie gewünscht bearbeitet werden. Ich meine jedoch, wenn Sie keine Vielzahl von Antworten implementieren möchten, ist es immer noch akzeptabel, nur eine 400 zu geben.
quelle