Ist es falsch, 202 "Akzeptiert" als Antwort auf HTTP GET zurückzugeben?

88

Ich habe eine Reihe von Ressourcen, deren Darstellungen träge erstellt werden. Die Berechnung zum Erstellen dieser Darstellungen kann je nach Serverlast, spezifischer Ressource und Mondphase zwischen einigen Millisekunden und einigen Stunden dauern.

Die erste für die Ressource empfangene GET-Anforderung startet die Berechnung auf dem Server. Wenn die Berechnung innerhalb weniger Sekunden abgeschlossen ist, wird die berechnete Darstellung zurückgegeben. Andernfalls wird der Statuscode 202 "Akzeptiert" zurückgegeben, und der Client muss die Ressource abfragen, bis die endgültige Darstellung verfügbar ist.

Der Grund für dieses Verhalten ist folgender: Wenn ein Ergebnis innerhalb weniger Sekunden verfügbar ist, muss es so schnell wie möglich abgerufen werden. Andernfalls ist es nicht wichtig, wann es verfügbar ist.

Aufgrund des begrenzten Speichers und des enormen Anforderungsvolumens sind weder NIO noch lange Abfragen eine Option ( dh ich kann nicht annähernd genug Verbindungen offen halten oder sogar alle Anforderungen in den Speicher einpassen; einmal "einige Sekunden" bestanden haben, ich bleibe bei den überschüssigen Anfragen). Ebenso sind die Client-Einschränkungen so, dass sie stattdessen keinen Abschlussrückruf verarbeiten können. Beachten Sie schließlich, dass ich nicht daran interessiert bin, eine "Factory" -Ressource zu erstellen, an die ein POST gesendet wird, da die zusätzlichen Roundtrips bedeuten, dass wir die stückweise Echtzeitbeschränkung mehr als gewünscht nicht erfüllen (außerdem ist es zusätzliche Komplexität; dies ist auch eine Ressource, die dies tun würde vom Caching profitieren).

Ich stelle mir vor, dass es einige Kontroversen über die Rückgabe eines 202 "Akzeptiert" -Statuscodes als Antwort auf eine GET-Anfrage gibt, da ich ihn in der Praxis noch nie gesehen habe und seine intuitivste Verwendung als Reaktion auf unsichere Methoden erfolgt, aber noch nie fand etwas speziell entmutigend. Bewahre ich nicht sowohl Sicherheit als auch Idempotenz?

Was denken die Leute über diesen Ansatz?

EDIT : Ich sollte erwähnen, dass dies für eine sogenannte Business Web API ist - nicht für Browser.

user359996
quelle
2
Ich persönlich denke, es ist gut, es ist genau die Definition von a 202. Dass es in der Praxis selten verwendet wird, liegt meiner Meinung nach eher daran, dass sich nur wenige Webentwickler für die richtigen Statuscodes interessieren, da sie eher an die Interaktion zwischen Browser und Benutzeragenten gewöhnt sind. In diesem Fall 202gibt a ihnen keinen sichtbaren Hinweis (geben Sie ihnen ein 200und sie sind glücklich). ..).
Wrikken
1
@ user359996, einfach verwenden 200. 202ist das, was es sein soll , aber in der Praxis erwarten die Leute es nicht 202.
Pacerier
Es braucht eine ETA für eine 200, um in der Praxis nützlich zu sein.
Rob

Antworten:

65

Wenn es sich um eine gut definierte und dokumentierte API handelt, 202klingt dies genau richtig für das, was passiert.

Wenn es für das öffentliche Internet ist, wäre ich zu besorgt über die Client-Kompatibilität. Ich habe so viele if (status == 200)fest codierte gesehen ... In diesem Fall würde ich a zurückgeben 200.

Außerdem gibt der RFC keinen Hinweis darauf, dass die Verwendung von 202 für eine GET-Anforderung falsch ist, während er in anderen Codebeschreibungen (z. B. 200) klare Unterschiede macht.

Die Anforderung wurde zur Verarbeitung angenommen, die Verarbeitung wurde jedoch nicht abgeschlossen.

Pekka
quelle
15

Wir haben dies für eine kürzlich durchgeführte Anwendung getan. Ein Client (benutzerdefinierte Anwendung, kein Browser) hat eine Abfrage gesendet, und der Server hat 202 mit einem URI an den "Job" zurückgegeben, der veröffentlicht wird. Der Client hat diesen URI verwendet, um nach dem abzufragen Ergebnis - dies scheint gut zu dem zu passen, was getan wurde.

Das Wichtigste dabei ist ohnehin, zu dokumentieren, wie Ihr Service / Ihre API funktioniert und was eine Antwort von 202 bedeutet.

nr
quelle
+1 Danke für deinen Kommentar. Guter Punkt zur Dokumentation. Bitte beachten Sie jedoch die klarstellenden Änderungen an meiner Frage (suchen Sie nach "Fabrik").
user359996
Nun, Sie können diesen URI in der Antwort weglassen, wenn Sie nur denselben URI abfragen möchten, den Sie ursprünglich angefordert haben. (Dokumentieren Sie einfach, wie das funktionieren sollte :-))
Nr.
Gute Idee, aber denk dran, ich möchte Caching, also kein POST. Darüber hinaus gibt der URI die Ressource an, keine Methode. Ich gehe eher RESTful als RPC vor (sorry, eine weitere nicht spezifizierte Einschränkung - meine schlechte).
user359996
Um genau zu sein, meine ich mit "RESTful" tatsächlich "ressourcenorientiert", was technisch etwas mehr ist als in den REST-Einschränkungen angegeben.
user359996
12

Soweit ich mich erinnern kann, soll GET eine Ressource zurückgeben, ohne den Server zu ändern. Möglicherweise wird die Aktivität protokolliert oder was haben Sie, aber die Anforderung sollte mit demselben Ergebnis erneut ausgeführt werden können.

POST hingegen ist eine Anforderung, den Status von etwas auf dem Server zu ändern. Einfügen eines Datensatzes, Löschen eines Datensatzes, Ausführen eines Jobs, so etwas. 202 wäre für einen POST geeignet, der zurückgegeben wird, aber noch nicht fertig ist, aber nicht wirklich eine GET-Anforderung.

Es ist alles sehr puritanisch und in freier Wildbahn nicht gut geübt, daher sind Sie wahrscheinlich sicher, wenn Sie 202 zurückgeben. GET sollte 200 zurückgeben. POST kann 200 zurückgeben, wenn es fertig ist, oder 202, wenn es nicht fertig ist.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Dlongnecker
quelle
4
Sehr gutes Denken, aber ich bin mir nicht sicher, ob es hier zutrifft: Nach dem, was das OP sagt, scheint dies eine richtige GET-Anfrage zu sein (da es nichts auf dem Server ändert), es dauert nur länger, es zu berechnen und einzugeben dieser Fall ist zu einem anderen Zeitpunkt abzurufen. Vielleicht kann das OP einen maßgeblichen Kommentar abgeben. Es ist für eine API, also ist es in Ordnung, für eine saubere Oberfläche "puritanisch" zu sein
Pekka
Oh, touche pekka. Du hast recht, GET ist der richtige Weg. Und ich glaube nicht, dass der HTTP-SPC GETs wirklich berücksichtigt hat, die noch nicht fertig sind. Also konnte er in beide Richtungen gehen
Dlongnecker
7
(Jetzt irrelevant) maßgeblicher Kommentar: Ja, ich betrachte dies als idempotent. Die Ressource wird weder geändert noch erstellt, sondern ihre Darstellung wurde noch nicht berechnet.
user359996
1
Wo steht das? Wenn ich 200 zurückgebe, sollte der Client erwarten, dass eine Darstellung zurückgegeben wurde, dies ist jedoch nicht der Fall.
user359996
1
Ich nehme es zurück. 202 entspricht anscheinend nicht nur GET oder POST. Allein die Einstellung, in der ich mich befand, als ich mir das Protokoll ansah, ließ mich feststellen, dass es 202 nur für GET-Anfragen gab. 202 sollte für Ihre Zwecke in Ordnung sein.
Dlongnecker
0

Im Falle einer Ressource, die eine Darstellung einer Entität haben soll, die durch eine ID eindeutig angegeben ist (im Gegensatz zu einer "Factory" -Ressource, wie in der Frage beschrieben), empfehle ich, bei der GET-Methode zu bleiben und in a Wenn die Entität / Darstellung aufgrund einer verzögerten Erstellung oder einer anderen vorübergehenden Situation nicht verfügbar ist, verwenden Sie den Antwortcode 503 Service Unavailable, der geeigneter ist und tatsächlich für Situationen wie diese entwickelt wurde.

Gründe hierfür finden Sie in den RFCs für HTTP selbst (überprüfen Sie die Beschreibung des 503-Antwortcodes) sowie in zahlreichen anderen Ressourcen.

Bitte vergleichen Sie den HTTP-Statuscode für vorübergehend nicht verfügbare Seiten . Obwohl es sich bei dieser Frage um einen anderen Anwendungsfall handelt, bezieht sie sich tatsächlich auf genau die gleiche Funktion von HTTP.

Hermes
quelle