it-swarm.com.de

400 vs 422 Antwort auf POST von Daten

Ich versuche herauszufinden, welcher Statuscode in den verschiedenen Szenarien mit einer "REST-ähnlichen" API, an der ich arbeite, korrekt ist. Angenommen, ich habe einen Endpunkt, der das POST'ing von Einkäufen im JSON-Format ermöglicht. Es sieht aus wie das:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

Was soll ich zurücksenden, wenn der Kunde mir "sales_tax" sendet (anstelle der erwarteten "Steuer")? Gegenwärtig kehre ich eine 400 zurück. Aber ich habe angefangen, mich diesbezüglich zu befragen. Sollte ich wirklich einen 422 zurückgeben? Ich meine, es ist JSON (das unterstützt wird) und es ist gültiges JSON, es enthält einfach nicht alle erforderlichen Felder.

313
David S

400 Bad Request scheint nun der beste HTTP/1.1-Statuscode für Ihren Anwendungsfall zu sein.

Zum Zeitpunkt Ihrer Frage (und meiner ursprünglichen Antwort) war RFC 7231 keine Sache; An diesem Punkt widersprach ich 400 Bad Request, weil RFC 2616 sagte (mit Betonung meiner):

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

und die Anfrage, die Sie beschreiben, ist syntaktisch gültiges JSON, das in syntaktisch gültigem HTTP eingeschlossen ist, und daher hat der Server keine Probleme mit der -Syntax der Anfrage.

Jedoch wie von Lee Saferite in den Kommentaren ausgeführt , RFC 7231, das RFC 2616 veraltet, tut dies nicht schließe diese Einschränkung ein :

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.


Jedoch vor dieser Neuformulierung (oder wenn Sie darüber streiten möchten, dass RFC 7231 nur ein vorgeschlagener Standard im Moment), 422 Unprocessable Entity scheint kein falscher HTTP-Statuscode für Ihren Anwendungsfall zu sein, da als die Einführung zu RFC 4918 besagt:

Während die von HTTP/1.1 bereitgestellten Statuscodes ausreichen, um die meisten von WebDAV-Methoden festgestellten Fehlerzustände zu beschreiben, gibt es einige Fehler, die nicht genau in die vorhandenen Kategorien fallen. Diese Spezifikation definiert zusätzliche Statuscodes, die für WebDAV-Methoden entwickelt wurden (Abschnitt 11).

Und die Beschreibung von 422 sagt:

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.

(Beachten Sie den Hinweis zur Syntax; ich vermute, dass 7231 auch 4918 teilweise überholt)

Dies klingt genau wie Ihre Situation, aber für den Fall, dass Zweifel bestanden, heißt es weiter:

Diese Fehlerbedingung kann beispielsweise auftreten, wenn ein XML-Anforderungstext wohlgeformte (d. H. Syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält.

(Ersetzen Sie "XML" durch "JSON" und ich denke, wir können uns darauf einigen, dass dies Ihre Situation ist.)

Nun werden einige Einwände dagegen erheben, dass es in RFC 4918 um "HTTP-Erweiterungen für das verteilte Erstellen und Versionsmanagement (WebDAV)" geht und dass Sie (vermutlich) nichts mit WebDAV zu tun haben und daher keine Dinge daraus verwenden sollten.

Angesichts der Wahl zwischen der Verwendung eines Fehlercodes im Originalstandard, der die Situation explizit nicht abdeckt, und eines Codes aus einer Erweiterung, die die Situation genau beschreibt, würde ich letzteren wählen.

Darüber hinaus bezieht sich RFC 4918, Abschnitt 21.4 auf HTTP-Statuscode-Registrierung (IANA Hypertext Transfer Protocol , wobei 422 gefunden werden kann.

Ich schlage vor, dass es völlig vernünftig ist, dass ein HTTP-Client oder -Server einen beliebigen Statuscode aus dieser Registrierung verwendet, sofern dies korrekt erfolgt.


Ab HTTP/1.1 hat RFC 7231 Traktion, verwenden Sie also einfach 400 Bad Request!

375
Kristian Glass

Um den Stand von 2015 widerzuspiegeln:

Verhaltensmäßig werden sowohl 400 als auch 422 Antwortcodes von Kunden und Vermittlern gleich behandelt, so dass es eigentlich keinen konkreten Unterschied macht, den Sie verwenden.

Allerdings würde ich davon ausgehen, dass 400 derzeit häufiger verwendet werden, und außerdem machen es die Erläuterungen, die HTTPbis-Spezifikation liefert, angemessener für die beiden Statuscodes:

  • Die HTTPbis-Spezifikation verdeutlicht die Absicht von 400, nicht nur für Syntaxfehler zu gelten. Der breitere Ausdruck "gibt an, dass der Server die Anforderung aufgrund eines als Clientfehler wahrgenommenen Ereignisses nicht verarbeiten kann oder wird" wird jetzt verwendet.
  • 422 ist speziell eine WebDAV-Erweiterung und wird in RFC 2616 oder in der neueren HTTPbis-Spezifikation nicht referenziert.

Für den Kontext ist HTTPbis eine Überarbeitung der HTTP/1.1-Spezifikation, mit der versucht wird, Bereiche zu klären, in denen Unklarheiten oder Inkonsistenzen bestehen. Sobald der genehmigte Status erreicht ist, wird RFC2616 ersetzt.

32
Tom Christie

400 Bad Request ist der richtige HTTP-Statuscode für Ihren Anwendungsfall. Der Code wird durch HTTP/0.9-1.1 RFC definiert.

Die Anforderung konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden. Der Kunde sollte die Anfrage NICHT ohne Änderungen wiederholen.

http://tools.ietf.org/html/rfc2616#section-10.4.1

422 Nicht verarbeitbare Entität ist in RFC 4918 - WebDav definiert. Beachten Sie, dass es im Vergleich zu 400 geringfügige Unterschiede gibt (siehe unten zitierten Text).

Diese Fehlerbedingung kann auftreten, wenn ein XML-Anforderungstext wohlgeformte (d. H. Syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält.

Um eine einheitliche Benutzeroberfläche zu gewährleisten, sollten Sie 422 nur für XML-Antworten verwenden und alle Statuscodes unterstützen, die von der Webdav-Erweiterung definiert werden, nicht nur 422.

http://tools.ietf.org/html/rfc4918#page-78

Siehe auch Mark Nottinghams Beitrag zu Statuscodes:

es ist ein Fehler, zu versuchen, jeden Teil Ihrer Anwendung „tief“ in HTTP-Statuscodes abzubilden. In den meisten Fällen ist die gewünschte Granularität viel gröber. Im Zweifelsfall ist es in Ordnung, die allgemeinen Statuscodes 200 OK, 400 Bad Request und 500 Internal Service Error zu verwenden, wenn keine bessere Übereinstimmung vorliegt .

Wie man über HTTP-Statuscodes nachdenkt

31
filip26

Es gibt keine richtige Antwort, da dies davon abhängt, wie die Definition von "Syntax" für Ihre Anfrage lautet. Das Wichtigste ist, dass Sie:

  1. Verwenden Sie die Antwortcodes konsistent
  2. Fügen Sie dem Antworttext so viele zusätzliche Informationen wie möglich hinzu, um den Entwicklern bei der Verwendung Ihrer API zu helfen, herauszufinden, was los ist. =

Bevor mich alle überraschen, weil ich sage, dass es hier keine richtige oder falsche Antwort gibt, möchte ich kurz erläutern, wie ich zu dem Schluss gekommen bin.

In diesem speziellen Beispiel handelt es sich bei der Frage des OP um eine JSON-Anforderung, die einen anderen Schlüssel als erwartet enthält. Nun ist der empfangene Schlüsselname vom Standpunkt der natürlichen Sprache zum erwarteten Schlüssel sehr ähnlich, aber er ist streng unterschiedlich und wird daher von einer Maschine (normalerweise) nicht als äquivalent erkannt.

Wie ich oben sagte, ist der entscheidende Faktor, was mit Syntax gemeint ist. Wenn die Anforderung mit dem Inhaltstyp application/json gesendet wurde, ist die Anforderung syntaktisch gültig, da sie eine gültige JSON-Syntax hat, aber nicht semantisch gültig es stimmt nicht mit dem überein, was erwartet wird. (unter der Annahme einer strengen Definition dessen, was die betreffende Anfrage semantisch gültig macht oder nicht).

Wenn andererseits die Anfrage mit einem spezifischeren benutzerdefinierten Inhaltstyp wie application/vnd.mycorp.mydatatype+json gesendet wurde, der möglicherweise genau angibt, welche Felder erwartet werden, würde ich sagen, dass die Anfrage leicht syntaktisch ungültig sein könnte, daher der 400 Antwort.

In dem fraglichen Fall gab es, da Schlüssel falsch war, nicht Wert, einen Syntax Fehler wenn es einen gab) Spezifikation für welche gültigen Schlüssel. Wenn es keine Spezifikation gab für gültige Schlüssel oder der Fehler war mit einem Wert, dann wäre es ein semantischer Fehler.

14
cdeszaq

Fallstudie: GitHub API

https://developer.github.com/v3/#client-errors

Vielleicht ist das Kopieren von bekannten APIs eine gute Idee:

Es gibt drei mögliche Arten von Clientfehlern bei API-Aufrufen, die Anforderungskörper empfangen:

Das Senden eines ungültigen JSON führt zu einer Antwort von 400 Bad Request.

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}

Das Senden des falschen Typs von JSON-Werten führt zu einer 400-Fehlerantwort.

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

Das Senden ungültiger Felder führt zu einer Antwort von 422 Unprocessable Entity.

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}

422 Unprocessable Entity Explained Aktualisiert: 6. März 2017

Was ist die nicht verarbeitbare Entität 422?

Ein 422-Statuscode tritt auf, wenn eine Anforderung korrekt aufgebaut ist, sie jedoch aufgrund semantischer Fehler nicht verarbeitet werden kann. Dieser HTTP-Status wurde in RFC 4918 eingeführt und ist insbesondere auf HTTP-Erweiterungen für Web Distributed Authoring und Versioning (WebDAV) ausgerichtet.

Es gibt einige Kontroversen darüber, ob Entwickler einen Fehler zwischen 400 und 422 an Clients zurückgeben sollen oder nicht (mehr zu den Unterschieden zwischen den beiden unten aufgeführten Status). In den meisten Fällen wird jedoch vereinbart, dass der 422-Status nur zurückgegeben wird, wenn Sie WebDAV-Funktionen unterstützen.

Eine Wort-für-Wort-Definition des 422-Statuscodes aus Abschnitt 11.2 in RFC 4918 finden Sie weiter unten.

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.

In der Definition heißt es weiter:

Diese Fehlerbedingung kann beispielsweise auftreten, wenn ein XML-Anforderungstext wohlgeformte (d. H. Syntaktisch korrekte), aber semantisch fehlerhafte XML-Anweisungen enthält.

400 vs 422 Statuscodes

Fehlerhafte Anforderungsfehler verwenden den 400-Statuscode und sollten an den Client zurückgegeben werden, wenn die Anforderungssyntax fehlerhaft ist, ungültige Anforderungsnachrichten enthält oder irreführendes Anforderungsrouting aufweist. Dieser Statuscode scheint dem Status der nicht verarbeitbaren Entität 422 ziemlich ähnlich zu sein. Eine kleine Information, die sie unterscheidet, ist jedoch die Tatsache, dass die Syntax einer Anforderungsentität für einen Fehler 422 korrekt ist, wohingegen die Syntax einer Anforderung, die eine 400 generiert Fehler ist falsch.

Die Verwendung des Status 422 sollte nur für ganz bestimmte Anwendungsfälle reserviert werden. In den meisten anderen Fällen, in denen ein Clientfehler aufgrund einer fehlerhaften Syntax aufgetreten ist, sollte der Status 400 Bad Request verwendet werden.

https://www.keycdn.com/support/422-unprocessable-entity/

4

Erstens ist das eine sehr gute Frage.

400 Bad Request - Wenn eine wichtige Information in der Anfrage fehlt

z.B. Der Autorisierungsheader oder der Inhaltstyp-Header. Was der Server unbedingt benötigt, um die Anfrage zu verstehen. Dies kann von Server zu Server unterschiedlich sein.

422 Nicht verarbeitbare Entität - Wenn der Anforderungshauptteil nicht analysiert werden kann.

Dies ist weniger schwerwiegend als 400. Die Anforderung hat den Server erreicht. Der Server hat bestätigt, dass die Anforderung die richtige Grundstruktur hat. Die Informationen im Anforderungshauptteil können jedoch nicht analysiert oder verstanden werden.

z.B. Content-Type: application/xml wenn der Anforderungshauptteil JSON ist.

Hier ist ein Artikel mit Statuscodes und deren Verwendung in REST APIs. https://metamug.com/article/status-codes-for-rest-api.php

2
user8029840

Ihr Fall: _HTTP 400_ ist aus Sicht von REST der richtige Statuscode für Ihren Fall, da das Senden syntaktisch falsch ist _sales_tax_ anstelle von tax, obwohl es sich um einen gültigen JSON handelt. Dies wird normalerweise von den meisten serverseitigen Frameworks erzwungen, wenn JSON Objekten zugeordnet wird. Es gibt jedoch einige REST Implementierungen, die neue key im JSON-Objekt ignorieren. In diesem Fall kann eine benutzerdefinierte Spezifikation _content-type_, die nur gültige Felder akzeptiert, serverseitig durchgesetzt werden.

Ideales Szenario für 422:

In einer idealen Welt wird 422 als Antwort bevorzugt und im Allgemeinen akzeptiert, wenn der Server den Inhaltstyp der Anforderungsentität und die Syntax der Anforderung versteht Die Entität ist korrekt, konnte die Daten jedoch nicht verarbeiten, da sie semantisch fehlerhaft sind.

Situationen von 400 über 422:

Denken Sie daran, dass der Antwortcode 422 ein erweiterter HTTP-Statuscode (WebDAV) ist. Es gibt immer noch einige HTTP-Clients/Front-End-Bibliotheken, die nicht für 422 vorbereitet sind. Für sie ist es so einfach wie "HTTP 422 ist falsch, weil es nicht HTTP ist" . Aus Service-Sicht ist 400 nicht ganz spezifisch.

In der Unternehmensarchitektur werden die Dienste hauptsächlich auf Service-Ebenen wie SOA, IDM usw. bereitgestellt. Sie dienen in der Regel mehreren Clients, von einem sehr alten nativen Client bis zu einem aktuellen HTTP-Client. Wenn einer der Clients HTTP 422 nicht verarbeitet, werden Sie aufgefordert, Ihren Antwortcode für alle Benutzer auf HTTP 400 zu aktualisieren oder zu ändern. Nach meiner Erfahrung ist dies heutzutage sehr selten, aber immer noch eine Möglichkeit. Daher ist immer eine sorgfältige Untersuchung Ihrer Architektur erforderlich, bevor Sie sich für die HTTP-Antwortcodes entscheiden.

Um mit solchen Situationen umzugehen, verwenden die Service-Layer normalerweise das Flag versioning oder setup configuration, damit Clients mit strikter HTTP-Konformität 400 senden, und senden 422 für den Rest von ihnen. Auf diese Weise bieten sie Abwärtskompatibilitätsunterstützung für vorhandene Konsumenten und gleichzeitig die Möglichkeit für die neuen Clients, HTTP 422 zu nutzen.


Das neueste Update für RFC7321 sagt:

_The 400 (Bad Request) status code indicates that the server cannot or
   will not process the request due to something that is perceived to be
   a client error (e.g., malformed request syntax, invalid request
   message framing, or deceptive request routing).
_

Dies bestätigt, dass Server HTTP 400 für ungültige Anforderungen senden können. 400 bezieht sich nicht mehr nur auf Syntaxfehler , 422 ist jedoch immer noch eine echte Antwort, sofern die Clients damit umgehen können.

1
YuVi