Wie wähle ich einen HTTP-Statuscode in der REST-API für "Noch nicht bereit, versuchen Sie es später erneut"? [geschlossen]

152

Ich entwickle eine RESTful-API, in der http://server/thingyapi/thingyblob/1234die mit dem Ding # 1234 verknüpfte Datei (auch bekannt als "blob") zum Herunterladen zurückgegeben wird. Aber es kann sein , dass der Antrag zu einem Zeitpunkt, wird die Datei nicht in dem Server vorhanden ist, aber auf jeden Fall wird zu einem späteren Zeitpunkt zur Verfügung steht. Es gibt einen Batch-Prozess auf dem Server, der alle Blobs für alle Dinger generiert. Thingy 1234 existiert bereits und seine Daten, außer dem Blob, sind bereits verfügbar. Der Server muss den Blob des Dings 1234 noch nicht generieren.

Ich möchte nicht 404 zurückgeben; Das ist für Dinge, die es nicht gibt. Dies ist ein Ding, das existiert, aber sein Blob wurde noch nicht generiert. Ein bisschen wie ein YouTube-Video, das "verarbeitet". Ich denke auch nicht, dass Umleitungscodes richtig wären. Es gibt keine "andere" URL zum Ausprobieren.

Was ist der richtige HTTP-Statuscode, der in einem solchen Fall zurückgegeben wird?

JCCyC
quelle
3
Etwas verwandt
Rob Hruska
7
Erstens, wenn das Ding 1234 noch keine GET-fähige Darstellung hat, in welchem ​​Sinne existiert es als Ressource (aus Sicht des Kunden)? Die Tatsache, dass sich innerhalb des Servers ein Job in der Warteschlange befindet, um 1234 zu erstellen, scheint nicht zu implizieren, dass die Ressource 1234 vorhanden ist. Zweitens, woher hat der Client die URI ... / thingyblob / 1234? Der Server hätte dem Client diesen URI wahrscheinlich nicht bereitstellen sollen, bis die Ressource tatsächlich GET-fähig war.
Andy Dennie
1
Ein Ding hat andere Eigenschaften, die es wert sind, anders als der Blob zu werden. Es ist nur der Blob, dessen Generierung Zeit braucht. Der Client erhält diese beispielsweise von server / thingyapi / thingy / 1234
JCCyC
10
Der HTTP-Standard enthält Anleitungen dazu, welche Statuscodes für welche Situationen verwendet werden sollen. Diese Frage ist daher nicht wirklich primär meinungsbasiert .
Raedwald
2
Wie wäre es mit 204"No Content"? Is zeigt an, dass der Server die Anforderung erfolgreich verarbeitet hat und [zu diesem Zeitpunkt] keinen Inhalt zurückgibt.
Timo

Antworten:

77

Ich schlage vor 202 - Accepted. Aus der Dokumentation :

Die Anforderung wurde zur Verarbeitung angenommen, die Verarbeitung wurde jedoch nicht abgeschlossen. [...] Es soll einem Server ermöglichen, eine Anforderung für einen anderen Prozess anzunehmen (möglicherweise einen stapelorientierten Prozess, der nur einmal pro Tag ausgeführt wird).

matsev
quelle
61
-1: Dies wäre sinnvoll für die Anforderung, die den Prozess initiiert, der schließlich "thingy # 1234" erstellt, nicht jedoch für die GET-Anforderung, die anschließend für "thingy # 1234" selbst ausgegeben wird. Insbesondere schlägt ein 202 vor, dass der Dienst als Ergebnis der GET-Anforderung die Daten für "thingy # 1234" zu einem späteren Zeitpunkt sendet. Das ist einfach nicht richtig.
Sam Harwell
7
Außerdem heißt es: "Die Entität, die mit dieser Antwort zurückgegeben wird, SOLLTE einen Hinweis auf den aktuellen Status der Anforderung und entweder einen Zeiger auf einen Statusmonitor oder eine Schätzung darüber enthalten, wann der Benutzer erwarten kann, dass die Anforderung erfüllt wird." Ein guter Weg, um den Kunden wissen zu lassen, dass der Blob noch nicht fertig ist, und ein Weg, um herauszufinden, wann er fertig ist.
Remy Lebeau
3
Ich würde argumentieren, dass "zur Verarbeitung angenommen" bedeutet, dass Sie die Anfrage speichern, um später darauf zu reagieren. Wenn es nur ignoriert wird, sollten Sie einen 4xx- oder 5xx-Code zurückgeben, um dem Client anzuzeigen, dass er es möglicherweise erneut versuchen möchte.
Luke
3
102 (Verarbeitung) scheint manchmal auch eine vernünftige Wahl zu sein, obwohl es sich um eine Webdav-Spezifikation handelt.
Akostadinov
2
Kann dieser Antwort nicht mehr widersprechen. Der Server gibt nichts zurück oder plant dies (führt aufgrund dieser Anforderung keine Verarbeitung durch - was für ein GET ohnehin nicht der Fall sein sollte). Daher steht die Ressource dem Client in gewisser Weise nicht zur Verfügung. Dies sollte als Fehler behandelt werden, damit kein 2XX-Code angemessen ist. Etwas im 4XX- oder 5XX-Raum. Die Anfrage wurde nicht "zur Bearbeitung angenommen" , die Anfrage wird in der Praxis verworfen
Adam
52

Das "Problem", so wie es ist, liegt auf der Serverseite: Der Client hat eine wohlgeformte Anfrage gestellt, aber der Server kann sie nicht erfüllen. Ich neige also zu einem "Server Error", 5xx Statuscode.

Quoth RFC 7231 (der aktuelle HTTP-Standard, Hervorhebung hinzugefügt):

Die Statuscodeklasse 5xx (Serverfehler) gibt an, dass dem Server bekannt ist, dass er einen Fehler begangen hat oder nicht in der Lage ist, die angeforderte Methode auszuführen . Außer bei der Beantwortung einer HEAD-Anfrage sollte der Server eine Darstellung senden, die eine Erläuterung der Fehlersituation enthält und angibt, ob es sich um eine vorübergehende oder eine dauerhafte Bedingung handelt.

Hinweis

  • "fehlerhaft oder nicht in der Lage, die Anforderung auszuführen ": Trotz des Titels "Serverfehler" sind sie nicht nur für Serverfehler gedacht.
  • " vorübergehend oder dauerhaft": Diese Codes eignen sich für vorübergehend nicht verfügbare Ressourcen wie Ihre.

Von den verfügbaren Codes würde ich sagen, 503 "Service nicht verfügbar" passte am besten:

Der Statuscode 503 (Service nicht verfügbar) zeigt an, dass der Server die Anforderung derzeit aufgrund einer vorübergehenden Überlastung oder geplanten Wartung nicht verarbeiten kann, 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.

Hinweis:

  • "wahrscheinlich nach einiger Verzögerung gelindert werden": wahr für Ihren Fall.
  • "vorübergehende Überlastung": Für Ihren Fall nicht pedantisch zutreffend. Es könnte jedoch argumentiert werden, dass die Stapelverarbeitung bereits durchgeführt worden wäre, wenn der Server die Anforderung gestellt hätte, wenn Ihr Server viel schneller gewesen wäre. Dies ist also eine Art "Überlastung": Der Client fordert Ressourcen schneller an, als der Server bereitstellen kann sie zur Verfügung.
  • Das Wiederholen ist für Ihren Dienst geeignet, daher sollte Ihre Antwort einen Retry-AfterWert enthalten. Sie können als Wert die geschätzte Abschlusszeit der nächsten Ausführung des Stapelprozesses oder das Ausführungsintervall des Stapelprozesses angeben.

Das Definieren Ihres eigenen 5xx-Statuscodes (z. B. 591) hätte, obwohl zulässig , die falsche Semantik:

Ein Client MUSS die Klasse eines Statuscodes verstehen, wie durch die erste Ziffer angegeben, und einen nicht erkannten Statuscode als dem x00-Statuscode dieser Klasse äquivalent behandeln

Clients würden Ihren eigenen Statuscode als 500 "Interner Serverfehler" behandeln , was nicht richtig wäre.

Raedwald
quelle
2
Ich kann nicht sehen, wie es besser als 202 ist: benramsey.com/blog/2008/04/…
JCCyC
4
@JCCyC Ihr Blog ist ein gutes Argument für die Rückgabe eines 202 als Antwort auf eine Anfrage zum Erstellen von etwas (POST oder PUT). Die Frage scheint zu sein, was für ein GET zurückgegeben werden soll.
Raedwald
@JCCyC es könnte als ein anderer Farbton der Nichtbereitschaft angesehen werden: Stellen Sie sich einen Ajax zu dieser Ressource vor. Bevorzugen Sie 202 als Erfolgsstatus oder 503 als Fehlerstatus? So können Sie sehen, welche Bedeutung Sie implizit im Zusammenhang mit der Reaktion Ihrer App auf die Antwort
bevorzugen
Ich mag auch den praktischen Aspekt von "Retry-After", der gut zu etwas
passt
1
NB: "Retry-After" kann auch mitgehen, 307 - TEMPORARY REDIRECTwas gut ist, wenn Sie die Client-Seite zwingen möchten, anderswo zu warten, während Ihre Ressource "fertig gemacht" wird
10.
28

Ich denke, dass 423 - Locked für diesen Zweck verwendet werden kann:

Der Statuscode 423 (gesperrt) bedeutet, dass die Quell- oder Zielressource einer Methode gesperrt ist. Diese Antwort sollte einen geeigneten Vor- oder Nachbedingungscode enthalten, z. B. "Lock-Token-Submission" oder "No-Conflicting-Lock".

Fernando Ortega
quelle
1
Hervorragende Antwort! Ich frage mich, warum es nicht mehr positive Stimmen gibt.
Lex82
10
Vielleicht, weil es sich um einen WebDAV-HTTP-Code handelt?
Stephan L
1
Von akka-http gibt es StatusCode RetryWith = reg (c (449) ("Wiederholen mit", "Die Anforderung sollte wiederholt werden, nachdem die entsprechende Aktion ausgeführt wurde.")), Wo die Aktion warten und erneut
versuchen
2
In vielerlei Hinsicht stimme ich dem zu. Ich habe eine ähnliche Situation (in meinem Fall Suche nach einem Index, der möglicherweise noch nicht ausgefüllt ist). Semantisch halte ich das für richtig. In der RFC für 423 heißt es jedoch: "Diese Antwort sollte einen geeigneten Vor- oder Nachbedingungscode enthalten, z. B." Lock-Token-Submission "oder" No-Conflicting-Lock "." Ich bin mir nicht sicher, wie ich das hier anwenden soll. Und persönlich würde ich mit 409 Conflict gehen, aber das wurde ohne Kommentare abgelehnt - nicht sicher warum?
Adam
22

Ich möchte nicht 404 zurückgeben; Das ist für Dinge, die es nicht gibt.

Die URL entspricht nicht einer Anfrage nach einem Ding.

http://server/thingyapi/thingyblob/1234

Der Client fordert einen Dingblob an, der nicht existiert. Wenn es existieren würde, würden Sie es ihnen geben.

404.

Funroll
quelle
1
Ich bin froh, dass jemand das gesagt hat! Ich kann nicht glauben, dass es so viele Menschen 503gibt, die eine angemessene Antwort finden. Ganz zu schweigen von einigen anderen seltsamen Vorschlägen.
Jason Desrosiers
Obwohl ich der Meinung bin, dass ein 404 hier die am besten geeignete Antwort ist, beantwortet er nicht die Frage des OP, wie angezeigt werden soll, wann das Ding verfügbar ist :-). Ich denke, das Retry-After-Feld scheint der beste Kandidat zu sein, aber es kann offiziell nur für 503- und 3xx-Codes verwendet werden. @ Jason: Ich denke, das erklärt einige der seltsamen Vorschläge.
Ron Deijkers
Ich denke, das ist die beste Antwort. Sie dürfen einen Textkörper in einer 404-Antwort zurückgeben. Der Körper könnte anzeigen, dass das Ding zu einem späteren Zeitpunkt verfügbar sein wird. Oder verwenden Sie auch den Retry-After-Header. Der Standard muss hier etwas gedehnt werden, da er diesen Fall nicht gut abdeckt.
WW.
4
Die Leute haben sich zu sehr an 404 gewöhnt, was bedeutet, dass die Seite nicht gefunden wurde, dass sie dies im Kontext einer API nicht logisch trennen können.
Der Muffin-Mann
1
Dies ist sooooo 404. Thingyblob existiert noch nicht oder nie. Für http ist es irrelevant, ob es jemals verfügbar sein wird. Im Moment existiert es nicht und es ist 404. Wann es verfügbar sein wird, ist ein weiteres Problem, das gelöst werden kann, indem eine Nachricht vom Server zum Client gesendet wird. Sayin thingyblob: 1234 verfügbar. Führen Sie einen get erneut und voila ..
100r
21

Eine weitere Option : 503 - Service Unavailable.

Brian Kelly
quelle
5
Laut W3C ist es nicht das, was Sie dem Client sagen möchten (obwohl dies in gewisser Weise "wiederkommen" bedeutet): "Der Server kann die Anforderung derzeit aufgrund einer vorübergehenden Überlastung oder Wartung des Servers nicht verarbeiten. Dies hat zur Folge Dies ist eine vorübergehende Bedingung, die nach einer gewissen Verzögerung behoben wird. Wenn bekannt, kann die Länge der Verzögerung in einem Retry-After-Header angegeben werden. Wenn kein Retry-After angegeben ist, sollte der Client die Antwort wie bei a behandeln 500 Antwort. "
Skalee
4
Der Dienst ist nicht nicht verfügbar, der Dienst ist verfügbar, aber die Verarbeitung ist nicht abgeschlossen. 503 ist also wahrscheinlich keine gute Idee.
Ishtiaque Khan
17

Da Ihre Ressource nicht bereit ist, wissen Sie wahrscheinlich, wann (ungefähr) sie verfügbar sein wird und wann der Client seine Anfrage erneut versuchen kann. Dies bedeutet, dass Sie möglicherweise den Retry-After-Header verwenden möchten . Dieser Header ist gültig mit 503 (Service nicht verfügbar), was bedeutet, dass die gesamte Site wegen Wartungsarbeiten nicht verfügbar ist, und 3xx (Umleitung) Antworten.

Meiner Meinung nach wäre 302 (gefunden) mit Retry-After-Header die beste Option, aber ich bin nicht sicher, ob das Feld Standort des Antwortheaders gleich der Anforderungs-URL sein kann. Es ist sowieso eine kreisförmige Weiterleitung.

Skalee
quelle
3
Selbst wenn dies zulässig ist und der Client die Unterstützung für den Retry-After-Header nicht implementiert hat, endet eine 3xx-Umleitung auf dieselbe Seite möglicherweise mit 503 ... (optional natürlich mit einem Retry-After-Header)
Ron Deijkers
1
Retry-After gilt auch für HTTP 429 "Too Many Requests", hinzugefügt von RFC 6585 (April 2012). Dies kann angebracht sein, wenn der Grund dafür, dass die Ressource noch nicht bereit ist, darin besteht, dass der Client dem Server zu viel Arbeit gegeben hat.
Silas S. Brown
8

409 Konflikt

Gibt an, dass die Anforderung aufgrund eines Konflikts in der Anforderung nicht verarbeitet werden konnte, z. B. aufgrund eines Bearbeitungskonflikts bei mehreren Aktualisierungen. [Quelle Wikipedia.]

Dies könnte angemessen sein.

Wenn Sie die Anfrage nicht durch Rücksendung der Daten erfüllen können, ist dies kein Erfolg. Ich denke, 202 schlägt vor, dass der Server die Anfrage in die Warteschlange gestellt hat und sie später erfüllen wird. In Ihrem Fall ist die Anforderung jetzt Daten und ist fehlgeschlagen. Wenn Sie es später erneut versuchen, handelt es sich um eine andere Anforderung.

Ich denke, Sie haben einen Konflikt. Sie möchten die Daten. Aber sie werden bearbeitet / aktualisiert. Dies wäre auch der Fall, wenn Thingy1234 bereits vorhanden wäre und zuvor erfolgreich heruntergeladen worden wäre, jetzt aber bearbeitet wurde und während der Bearbeitung nicht verfügbar war.

J Moore
quelle
2
Ich bin mir nicht sicher, warum dies abgelehnt wurde. Scheint mir die richtige Antwort zu sein. Aus dem RFC: "Der Statuscode 409 (Konflikt) zeigt an, dass die Anforderung aufgrund eines Konflikts mit dem aktuellen Status der Zielressource nicht abgeschlossen werden konnte. Dieser Code wird in Situationen verwendet, in denen der Benutzer den Konflikt möglicherweise lösen kann und Senden Sie die Anforderung erneut. "Sie haben nach einer Ressource gefragt, die der Server nicht zurückgeben kann, da der Server diese Ressource gerade aktualisiert - dh aufgrund des aktuellen Status der Ressource. Der Client kann dies beheben, indem er wartet und erneut einreicht
Adam
1
@Adam Ich denke, die Implikation in "Benutzer könnte in der Lage sein, den Konflikt zu lösen" ist, dass etwas an der Wiedervorlage anders wäre, als nur zu warten.
Ganzheitlicher Entwickler
3

501 - Nicht implementiert

Genau so, wie es sich anhört. Eine Funktion, die noch nicht implementiert ist, aber zukünftige Verfügbarkeit impliziert.

Hier ist ein Link zu einer Zusammenfassung von 5xx Fehlern .

Dan
quelle
4
Bei dieser Frage scheint die Funktion selbst vorhanden zu sein, das angeforderte Element jedoch nicht.
Luke
@Luke 501s Beschreibung aus dem Link in meiner Antwort: '... es fehlt die Fähigkeit, die Anfrage zu erfüllen. Normalerweise impliziert dies eine zukünftige Verfügbarkeit. Dies erfüllt genau das, was das OP verlangt hat. Unabhängig davon, ob sich die Daten auf seinen Servern oder in der Datenbank befinden oder nicht. Das Endergebnis ist, dass es derzeit nicht über die API zugänglich ist. Daher kann die API die Anforderung nicht erfüllen, möchte jedoch implizieren, dass sie in Zukunft über den http-Code verfügbar sein wird.
Dan