Rückgabe von http 200 OK mit Fehler im Antworttext

74

Ich frage mich, ob es richtig ist, zurückzukehren, HTTP 200 OKwenn auf der Serverseite ein Fehler aufgetreten ist (die Fehlerdetails wären im Antworttext enthalten).

Beispiel:

  1. Wir senden HTTP GET
  2. Auf der Serverseite ist etwas Unerwartetes passiert.
  3. Server gibt HTTP 200 OKStatuscode mit Fehlern in einer Antwort (z {"status":"some error occurred"})

Ist das das richtige Verhalten oder nicht? Sollten wir den Statuscode auf etwas anderes als 200 ändern?

krzakov
quelle
12
HTTP 200 bedeutet, dass die Übertragung auf http-Ebene in Ordnung ist. Dies hat nichts mit Erfolg oder Misserfolg Ihres "Geschäftscodes" zu tun. In diesem Fall zeigt das HTTP 200 an, dass Ihre "Business Code-Fehlermeldung" erfolgreich übertragen wurde ;-) Alternativ können Sie Ihren Server mit HTTP 500 antworten lassen, was "interner Fehler" bedeutet. Dies ist eher typisch für technische oder nicht behebbare Probleme auf dem Server.
Geert3
Kann das jemand bestätigen? Ich habe mit einigen Programmierern gesprochen und kann unterschiedliche Meinungen hören.
krzakov
2
Bitte verwenden Sie stattdessen den Code 412.
Dima Tisnek
6
Wenn Sie sich die beiden widersprüchlichen Antworten ansehen, ist dies genau der Grund, warum der Stapelüberlauf die Diskussion anregen sollte.
Wobbily_col

Antworten:

102

Nein, das ist sehr falsch.

HTTP ist ein Anwendungsprotokoll. 200 impliziert, dass die Antwort eine Nutzlast enthält, die den Status der angeforderten Ressource darstellt. Eine Fehlermeldung ist normalerweise keine Darstellung dieser Ressource.

Wenn während der Verarbeitung von GET etwas schief geht, lautet der richtige Statuscode 4xx ("Sie haben es vermasselt") oder 5xx ("Ich habe es vermasselt").

Julian Reschke
quelle
10
Nein, ich bin völlig anderer Meinung als der erste Teil, der besagt, dass es in Ordnung wäre, 200 zurückzugeben.
Julian Reschke
1
Bitte beachten Sie meinen Kommentar zur anderen Antwort.
Geert3
2
Was ich denke 200 OK Fehler kann in einigen Fällen angemessen sein. In diesem Fall fordert der Client bei einer GET-Anfrage einige Ressourcen dazu auf, nicht den Ressourcenclient zu erhalten, nach dem er gefragt hat, sondern etwas anderes, das nicht stimmt. Wenn es sich um einen Serverfehler 5XX handelt, wenn clientseitig 4XX, z. B. die angeforderte Ressource, nicht vorhanden ist 404. Meine Meinung.
Freitag,
9
Nachdem ich kürzlich Erfahrungen mit einer sehr großen Fortune 500-E-Commerce-Website gesammelt habe, muss ich dieser Antwort nicht zustimmen, was bedeutet, dass 200 nicht für Fehler verwendet werden. Insbesondere diese Firma gibt alles als 200 OK zurück. Alle Fehler, die von Spring Java behandelt werden können, werden als 200 zurückgegeben, und im Hauptteil steht eine Fehlereigenschaft zur Verfügung. So einfach ist das. Sie müssen nicht herausfinden, welcher Fehler zu welchem ​​undurchsichtigen HTTP-Code gehört.
Programmierer
3
"HTTP ist ein Anwendungsprotokoll." Nun, während Wikipedia mit dieser Definition übereinstimmt , muss gesagt werden, dass sich die Anwendung hier auf die IP-Anwendungsschicht bezieht - in der Wikipedia HTTP, Telnet, FTP und SSH auflistet - alle Anwendungen der IP-Kommunikation. Dies ist nicht dasselbe wie meine Anwendungs- / Geschäftslogik, die diese Kommunikation verwendet. Das Senden eines HTTP 200 mit einer anwendungsspezifischen Fehlermeldung ist daher durchaus sinnvoll.
Jeff Ward
38

HTTP-Statuscodes sagen etwas über das HTTP-Protokoll aus. HTTP 200bedeutet, dass die Übertragung auf HTTP-Ebene in Ordnung ist (dh die Anfrage war technisch in Ordnung und der Server konnte ordnungsgemäß antworten). Auf dieser Wiki-Seite finden Sie eine Liste aller Codes und ihrer Bedeutung.

HTTP 200 hat nichts mit Erfolg oder Misserfolg Ihres "Geschäftscodes" zu tun. In Ihrem Beispiel HTTP 200ist dies ein akzeptabler Status, der angibt, dass Ihre "Business Code-Fehlermeldung" erfolgreich übertragen wurde, vorausgesetzt, keine technischen Probleme verhinderten die ordnungsgemäße Ausführung der Geschäftslogik.

Alternativ können Sie Ihren Server antworten lassen, HTTP 5xxwenn technische oder nicht behebbare Probleme auf dem Server aufgetreten sind. Oder HTTP 4xxwenn die eingehende Anforderung Probleme hatte (z. B. falsche Parameter, unerwartete HTTP-Methode ...). Diese weisen wiederum auf technische Fehler hin, während KEINE technischen Fehler HTTP 200angezeigt werden, übernehmen jedoch keine Garantie für Geschäftslogikfehler.

Zusammenfassend: JA, es ist gültig, Fehlermeldungen (für nicht technische Probleme) in Ihrer http-Antwort zusammen mit dem HTTP-Status 200 zu senden. Ob dies für Ihren Fall gilt, liegt bei Ihnen. Wenn der Client beispielsweise nach einer Datei fragt, die nicht vorhanden ist, ähnelt dies eher einer 404. Wenn auf dem Server eine Fehlkonfiguration vorliegt, kann dies eine sein 500. Wenn der Kunde nach einem Sitzplatz in einem ausgebuchten Flugzeug fragt, ist dies der Fall, 200und Ihre "Implementierung" bestimmt, wie dies erkannt / gehandhabt werden soll (z. B. JSON-Block mit a { "booking","failed" }).

geert3
quelle
8
Sehen. HTTP-Statuscodes sind technische Antworten, NICHT Geschäftslogikantworten. Ich kann mir sehr gut eine HTTP / REST-API vorstellen, bei der HTTP 200 für offensichtlich fehlerhafte Geschäftslogik zurückgegeben wird. Zum Beispiel: Ich bin ein HTTP-Kunde, der einen Flug in einem Flugzeug bucht. Alle meine Parameter sind in Ordnung, technisch kein Grund für HTTP 4xx. Server ist fehlerfrei, kein HTTP 5xx. Trotzdem ist das Flugzeug voll. Die Antwort ist ein Block von JSON, der diese Tatsache erklärt : {"booking":"failed","reason":"plane is full"}. Es ist vollkommen in Ordnung, ein HTTP 200 zu erhalten, tatsächlich (IMHO) wäre dies der EINZIGE gültige HTTP-Statuscode.
Geert3
23
"HTTP 200 hat nichts mit Erfolg oder Misserfolg Ihres" Geschäftscodes "zu tun - ja, das tut es. HTTP ist ein Anwendungsprotokoll, dessen Statuscodes dies widerspiegeln. Siehe RFC 7231, Abschnitt 6 : " Das Statuscodeelement ist a dreistelliger ganzzahliger Code, der das Ergebnis des Versuchs angibt, die Anforderung zu verstehen und zu erfüllen " ," erfüllen "eine erfolgreiche Verarbeitung der Anforderung. Wenn zu irgendeinem Zeitpunkt in der Anwendung ein Fehler auftritt (ob versucht wird, einen Sitzplatz vollständig zu buchen) Flug ist ein Fehler ist eine andere Diskussion), sollten Sie keinen 2xx Statuscode zurückgeben.
CodeCaster
11
Schauen Sie sich die 4xx- und 5xx-Codes an. Sie sind eindeutig für technische Fragen gedacht, und "die Anfrage verstehen und erfüllen" sollte in diesem Sinne verstanden werden. Der Server kann die Anforderung nicht verstehen, wenn sie einen nicht unterstützten Medientyp (415) hat oder die Methode nicht zulässig ist (405). Der Server kann eine Anforderung nicht erfüllen, wenn das Bandbreitenlimit überschritten wird (509) oder ein Netzwerk-Lesezeitlimit aufgetreten ist (598). Die Buchung eines Sitzplatzes in einem vollen Flugzeug hat jedoch nichts mit diesen Problemen zu tun, und hier wurde die Anfrage technisch verstanden und erfüllt, obwohl das Flugzeug voll ist, also: HTTP 200.
geert3
13
Um meinen Standpunkt anhand eines praktischen Beispiels zu beweisen. Die Google Maps REST-API. developer.google.com/maps/documentation/directions/… Alle Statuscodes und Fehlermeldungen werden in JSON / XML-Blöcken zurückgegeben, aber in jedem Fall wird HTTP 200 auf HTTP-Ebene zurückgegeben.
Geert3
8
Interessanterweise habe ich versucht, meinen Kommentar zu bearbeiten, weil ich ihn versehentlich eingereicht habe, bevor ich fertig war, und SO antwortete mit 500 'Sie können Ihren Kommentar nur für 5 Minuten bearbeiten'. Obwohl meine Einreichung "erfolgreich" war und der Fehler auf meiner Seite war, antwortete sie mit 500. ¯_ (ツ) _ / ¯ Ich wollte auch Ihre Seite des Arguments als gültig unterstützen, obwohl es für diese bestimmte Antwort wahrscheinlich ist nicht.
Radixhound
11

Selbst wenn ich einen Geschäftslogikfehler als HTTP-Code zurückgeben möchte, gibt es keinen solchen akzeptablen HTTP-Fehlercode für diese Fehler, anstatt HTTP 200 zu verwenden, da dadurch der tatsächliche Fehler falsch dargestellt wird.

HTTP 200 ist also gut für Fehler in der Geschäftslogik. Alle Fehler, die durch HTTP-Fehlercodes abgedeckt sind, sollten diese verwenden.

Grundsätzlich bedeutet HTTP 200, welcher Server die Benutzeranfrage korrekt verarbeitet (falls keine Sitzplätze im Flugzeug vorhanden sind, spielt es keine Rolle, dass die Benutzeranforderung korrekt verarbeitet wurde, und es kann sogar nur eine Anzahl verfügbarer Sitzplätze im Flugzeug zurückgegeben werden Es gibt überhaupt keine Geschäftslogikfehler oder diese Geschäftslogik kann sich auf der Clientseite befinden. Geschäftslogikfehler sind eine abstrakte Bedeutung, aber HTTP-Fehler sind eindeutiger.

Alexanderius
quelle
5

Zur Verdeutlichung sollten Sie HTTP-Fehlercodes verwenden, sofern diese zum Protokoll passen, und keine HTTP-Statuscodes zum Senden von Geschäftslogikfehlern verwenden .

Fehler wie unzureichendes Gleichgewicht , keine Kabinen verfügbar , fehlerhafter Benutzer / Passwort qualifizieren sich für den HTTP-Status 200mit anwendungsspezifischer Fehlerbehandlung im Antworttext.

Siehe diese Software-Engineering-Antwort :

Ich würde sagen, es ist besser, explizit über die Trennung von Protokollen zu sprechen. Lassen Sie den HTTP-Server und den Webbrowser ihr eigenes Ding machen, und lassen Sie die App ihr eigenes Ding machen. Die App muss in der Lage sein, Anforderungen zu stellen, und sie benötigt die Antworten - und ihre Logik hinsichtlich der Anforderung und Interpretation der Antworten kann komplexer (oder weniger) sein als die HTTP-Perspektive.

vedant
quelle
Dies mag Ansichtssache sein, aber ich bin anderer Meinung. Diese Fehler treten aus einem Grund auf. Sie müssen keine Möglichkeit neu erfinden, um Standardfehler zu senden. Verwenden Sie einfach die HTTP-Spezifikation. Wenn die Anfrage fehlerhaft ist, senden Sie 400, wenn der Benutzer keinen Zugriff auf die Ressource hat, senden Sie 403 usw. httpstatuses.com
Alexandre Testu
2

Ich denke, die Leute haben der Anwendungslogik gegenüber der Protokollsache zu viel Gewicht beigemessen. Wichtig ist, dass die Antwort sinnvoll ist. Was ist, wenn Sie eine API haben, die eine dynamische Ressource bedient, und eine Anforderung für X gestellt wird, die von der Vorlage Y mit Daten Z abgeleitet ist und entweder Y oder Z derzeit nicht verfügbar sind? Ist das ein Geschäftslogikfehler oder ein technischer Fehler? Die richtige Antwort lautet: "Wen interessiert das?"

Ihre API und Ihre Antworten müssen verständlich und konsistent sein. Es sollte einer Spezifikation entsprechen und diese Spezifikation sollte definieren, was eine gültige Antwort ist. Etwas, das einer gültigen Antwort entspricht, sollte einen 200-Code ergeben. Etwas, das nicht einer gültigen Antwort entspricht, sollte einen 4xx- oder 5xx-Code ergeben, der angibt, warum keine gültige Antwort generiert werden konnte.

Wenn die Definition einer gültigen Antwort in Ihrer Spezifikation dies zulässt { "error": "invalid ID" }, ist die Antwort erfolgreich. Wenn Ihre Spezifikation diese Anpassung nicht vornimmt, wäre es eine schlechte Entscheidung, diese Antwort mit einem 200-Code zurückzugeben.

Ich würde eine Analogie zum Aufrufen einer Funktion ziehen parseFoo. Was passiert, wenn Sie anrufen parseFoo("invalid data")? Gibt es ein Fehlerergebnis zurück (möglicherweise null)? Oder wirft es eine Ausnahme? Viele werden eine fast religiöse Position einnehmen, ob der eine oder der andere Ansatz korrekt ist, aber letztendlich liegt es an der API-Spezifikation.

"Das Statuscode-Element ist ein dreistelliger ganzzahliger Code, der das Ergebnis des Versuchs liefert, die Anforderung zu verstehen und zu erfüllen."

Offensichtlich gibt es Meinungsverschiedenheiten darüber, ob die "erfolgreiche Rückgabe eines Fehlers" einen HTTP-Erfolg oder -Fehler darstellt. Ich sehe verschiedene Leute, die die gleichen Spezifikationen unterschiedlich interpretieren. Wählen Sie also eine Seite, aber akzeptieren Sie auch, dass die ganze Welt Ihnen nicht zustimmen wird. Mich? Ich befinde mich irgendwo in der Mitte, aber ich werde einige vernünftige Überlegungen anstellen.

  1. Wenn Ihr serverseitiger Code beim Versenden einer Anforderung eine unerwartete Ausnahme abfängt, klingt dies wie die Definition von a 500 Internal Server Error. Dies scheint die Situation von OP zu sein. Die Anwendung sollte a nicht 200für unerwartete Fehler zurückgeben, sondern auch Punkt 3.
  2. Wenn Ihr serverseitigen Code sollte anmutig die Lage sein, eine bestimmte ungültige Eingabe handhaben , und es keine „außergewöhnliche“ Fehlerbedingung dar, Ihre spec sollten aufnehmen HTTP 200 - Antworten , die sinnvollen diagnostische Informationen liefern.
  3. Vor allem: Haben Sie eine Spezifikation. Machen Sie es konsistent. Bleibe dabei.

In der Situation von OP klingt es so, als hätten Sie einen De-facto-Standard, bei dem nicht behandelte Ausnahmen eine 200 mit einem unterscheidbaren Antwortkörper ergeben. Es ist nicht ideal, aber wenn es nicht kaputt geht und aktiv Probleme verursacht, müssen Sie wahrscheinlich größere, wichtigere Probleme lösen.

Snarf
quelle
1

HTTP Ist das Protokoll für die Übertragung von Daten über das Internet.

Wenn diese Übertragung aus irgendeinem Grund unterbrochen wird, erfahren Sie anhand der HTTP-Fehlercodes, warum sie nicht an Sie gesendet werden kann.

Die übertragenen Daten werden nicht von HTTP-Fehlercodes verarbeitet. Nur die Übertragungsmethode.

HTTP kann nicht sagen "Ok, diese Antwort ist Gobbledigook, aber hier ist es". es sagt nur 200 OK.

dh: Ich habe meine Aufgabe erledigt, es zu Ihnen zu bringen, der Rest liegt bei Ihnen.

Ich weiß, dass dies bereits beantwortet wurde, aber ich habe es in Worte gefasst, die ich verstehen kann. Entschuldigung für jede Wiederholung.

Chris Groves
quelle
Lassen Sie mich auch sagen, dass es an den Programmierern und Entwicklern liegt, serverseitige Fehler ordnungsgemäß zu melden und den Benutzer wissen zu lassen, welche Art von Problem auf der Serverseite vorliegt. zB Entschuldigung, diese Seite ist kaputt, oder zB bin ich gerade damit beschäftigt, meine Datenbank zu aktualisieren. Sei bald bei dir.
Chris Groves
1

Ich denke, diese Art von Problemen ist gelöst, wenn wir über das wirkliche Leben nachdenken.

Schlechte Praxis:

Beispiel 1:

Darling everything is FINE/OK (HTTP CODE 200) - (Success):
{
  ...but I don't want us to be together anymore!!!... (Error)
  // Then everything isn't OK???
}

Beispiel 2:

You are the best employee (HTTP CODE 200) - (Success):
{
  ...But we cannot continue your contract!!!... (Error)
  // Then everything isn't OK???
}

Gute Praktiken:

 Darling I don't feel good (HTTP CODE 400) - (Error):
{
  ...I no longer feel anything for you, I think the best thing is to separate... (Error)
  // In this case, you are alerting me from the beginning that something is wrong ...
}

Dies ist nur meine persönliche Meinung, jeder kann sie so umsetzen, wie es am bequemsten ist oder am nötigsten ist.

Hinweis: Die Idee für diese Erklärung stammt von einem großartigen Freund @diosney

Jose Carlos Ramos Carmenates
quelle