Wir erstellen einen REST-Service, dessen Ausführung ca. 5 Minuten dauert. Es wird nur ein paar Mal pro Tag von einer internen App aufgerufen. Gibt es ein Problem bei der Verwendung einer REST-Anforderung (dh HTTP), die 5 Minuten dauert?
Müssen wir uns über Timeouts Gedanken machen? Sollen wir die Anfrage in einem separaten Thread auf dem Server starten und den Client nach dem Status fragen lassen?
Wenn Sie davon ausgehen, dass Sie HTTP-Timeouts mit dem von Ihnen gewählten Framework konfigurieren können, können Sie dies über ein GET anfordern und sich nur 5 Minuten lang aufhängen.
Es kann jedoch flexibler sein, eine Ausführung über einen POST zu initiieren, eine Quittung (eine Zahl / ID, was auch immer) zu erhalten und dann 5 Minuten später ein GET zu verwenden (und vielleicht wiederholen, dass Ihre Prozedur nicht dauert) genau 5 Minuten jedes Mal). Wenn die Anfrage noch nicht abgeschlossen ist, geben Sie einen entsprechenden HTTP-Fehlercode zurück (404 vielleicht, aber was würden Sie für einen GET mit einem nicht vorhandenen Empfang zurückgeben?), Oder geben Sie die Ergebnisse zurück, falls verfügbar.
Dies ist ein Ansatz.
Erstellen Sie eine neue Anforderung zum Ausführen von ProcessXYZ
%Vor%Wenn Sie den aktuellen Status der Anfrage sehen möchten:
%Vor%Wenn die Anfrage beendet ist, sehen Sie etwas wie
%Vor%Mit diesem Ansatz können Sie sich leicht vorstellen, was die folgenden Anforderungen ergeben würden
%Vor%Wie Brian Agnew darauf hinweist, sind 5 Minuten völlig überschaubar, wenn man Ressourcen verschwendet, wenn man die Timeout-Einstellungen kontrollieren kann. Andernfalls müssen mindestens zwei Anforderungen gestellt werden: Die erste, um den ergebniserzeugenden Prozess ins Rollen zu bringen, und die zweite (und dritte, vierte, etc. , wenn das Ergebnis länger dauert als erwartet, um zu kompilieren) um nach dem Ergebnis zu fragen.
Brian Agnew und Darrel Miller schlagen beide ähnliche Ansätze für den Ansatz mit zwei (+) - Schritten vor: POST eine Anforderung an einen Factory-Endpunkt, einen Job auf dem Server starten und später das Ergebnis vom zurückgegebenen Ergebnisendpunkt abrufen.
Obwohl das obige eine sehr allgemeine Lösung ist und tatsächlich dem Buchstaben der REST-Beschränkungen folgt, riecht es sehr nach RPC. Das heißt, anstatt zu sagen: "Stellen Sie mir eine Darstellung dieser Ressource zur Verfügung, es heißt" Führen Sie diesen Job "(RPC) und dann" liefern Sie mir eine Darstellung der Ressource, die das Ergebnis der Ausführung des Jobs "(REST) ist. BEARBEITEN: Ich spreche hier sehr locker. Um es klar zu stellen: dies alles unterläuft nicht explizit den REST-Einschränkungen , aber es ähnelt sehr dem Hinzufügen eines nicht-REST-orientierten Ansatzes in RESTs Kleidung, wobei die Vorteile ( zB Caching, Idempotenz) dabei.
Als solches würde ich eher vorschlagen, dass, wenn der Client zuerst versucht, die Ressource zu erhalten, der Server mit 202 "Akzeptiert" antworten sollte ( Ссылка ), vielleicht mit" in 5 Minuten zurück "irgendwo in der Antworteinheit. Danach kann der Client den gleichen Endpunkt abfragen , um das Ergebnis abzurufen, falls verfügbar (andernfalls 202 zurückgeben und es später erneut versuchen).
Einige zusätzliche Vorteile dieses Ansatzes bestehen darin, dass Einwegressourcen (wie Jobs) nicht unnötig erstellt werden, zwei separate Endpunkte nicht abgefragt werden müssen (Fabrik und Ergebnis), und ebenso muss der zweite Endpunkt nicht durch das Parsen des Antwort von der ersten, also einfacher. Außerdem können Ergebnisse "frei" (code-weise) zwischengespeichert werden. Legen Sie die Ablaufzeit des Caches im Ergebniskopf fest, je nachdem, wie lange die Ergebnisse in gewisser Weise für Ihre Problemdomäne "gültig" sind.
Ich wünschte, ich könnte dies ein Lehrbuchbeispiel für einen "ressourcenorientierten" Ansatz nennen, aber ironischerweise schlägt Kapitel 8 von "RESTful Web Services" den Factory-Ansatz mit zwei Endpunkten vor. Geh Figur.
Wenn Sie beide Enden steuern, können Sie tun, was Sie wollen. Z.B. Browser neigen dazu, HTTP-Anfragen mit "Verbindung schließen" -Kopfzeilen zu starten, so dass Sie mit weniger Optionen übrig bleiben; -)
Denken Sie daran, dass Sie, wenn Sie einige NAT / Firewalls dazwischen haben, einige Drop-Verbindungen haben, wenn sie für einige Zeit inaktiv sind.
Kann ich vorschlagen, ein "Callback" -Verfahren zu registrieren? Der Client gibt die Anfrage mit einem "Rückruf-Endpunkt" an den Server aus, erhält ein "Ticket". Sobald der Server fertig ist, "ruft" er den Client zurück ... oder der Client kann den Status der Anfrage über die Ticket-ID überprüfen.
Tags und Links rest asynchronous web-services