RESTで非同期操作を処理するためのアプローチと、それらの長所と短所を理解する必要があります。私が見つけたいくつかのアプローチ:
リソースベース:操作のステータスがステータスとしてモデル化される場合。ユーザーが非同期のREST呼び出し(PUT、POSTなど)を行うと、Accepted
またはIn-Progress
応答(202
)を取得します。さらに、ステータスURIはGETを介して繰り返しポーリングされ、操作の実行からのステータス/進行状況/メッセージを確認します。
質問:このリソースはサーバーでどのくらいアクティブにする必要がありますか?クライアントが操作の間に大きな間隔でポーリングする場合、どのようにステータスを返しますか?実行ステータスを永続化することは機能するようです。しかし、いつアーカイブ/削除するのか、この種の標準的なアプローチはどのくらい持続しますか?
コールバックベース:コールバックURIを持つために非同期リクエストが必要な場合。リクエストは非同期で処理され、完了すると、操作ステータス/結果を使用してコールバックURIが呼び出されます。
質問:これはよりエレガントで、サーバー側のオーバーヘッドが少ないようです。しかし、コールバックサーバーが断続的にダウンしたり、応答しなかったりするシナリオを処理するにはどうすればよいでしょうか。コールバックURIが再試行構成も提供する典型的な再試行を実装しますか?このアプローチに他の欠点はありますか?
サーブレット3.0非同期サポート: HTTPクライアントがJavaサーブレットに接続する場合。サーブレットは、明示的に閉じられるまで、また閉じられたクライアントとサーバーが非同期で通信できるようになるまで開いたままになります。
質問:サーブレット3.0仕様なので、Spring RESTの実装であるJerseyは、現時点ではこのアプローチを利用していないと思います。同様のアプローチまたはそれを可能にする方法へのポインタを利用する特定のREST実装はありますか?
他のアプローチ、多分商業的なアプローチ?
Spring 3.2以降は、サーブレット3.0の非同期機能をサポートしています。 春のブログ から:
callableを返すように変更することで、既存のコントローラーメソッドを非同期にすることができます。たとえば、ビュー名を返すコントローラーメソッドは、代わりにCallableを返すことができます。 Personというオブジェクトを返す@ResponseBodyは、代わりにCallableを返すことができます。また、他のコントローラーの戻り値タイプについても同じことが言えます。
Jersey 2+は、非同期サーバーもサポートしています。リファレンスドキュメントの 非同期サービスとクライアント の章を参照してください。
アプローチは、最初のリクエストから操作の終了までの時間差に依存すると思います。
私は今同じ状況に取り組んでおり、Location
ヘッダー応答を使用して、ステータスを確認するために監視できるリソースを提供する一般的なアプローチを見つけました(もちろんポーリングによって)。それが最善のようですが、私の場合、リソースを作成していないため、ステータスを確認する場所がありません(非同期プロセスはキャッシュページを作成するだけです)。
いつでも独自のヘッダーを使用して、操作を完了するための推定時間を与えることができます。とにかく、私はRetry-After
ヘッダーを使用して推定時間を与えることを考えています。皆さんはどう思いますか?
これは古いことは知っていますが、ここでチャイムを鳴らして、ステートレス環境でスケールアウトできるものが必要な場合は、最初のオプションを選択する必要があると思いました。基盤となる操作はどこでも実行でき、結果をredisのようなものにすると、クライアントが後続のポーリング要求を行うWebサーバーには関係ありません。通常、クライアントに送信した応答にポーリング間隔を設定します。結果の準備ができたら、URIに結果のIDを含むSEEOTHERをクライアントに返します。