最終的な処理のために長時間実行されるタスクをキューに入れることをサポートするRESTful APIを構築しています。
このAPIの一般的なワークフローは次のとおりです。
- ユーザーがフォームに入力する
- クライアントがデータをAPIに投稿します
- APIは202 Acceptedを返します
- クライアントはユーザーをそのリクエストの一意のURLにリダイレクトします(
/results/{request_id}
) - 〜最終的に〜
- クライアントは再度URLにアクセスし、そのページで結果を確認します。
問題はステップ6にあります。ユーザーがページにアクセスするたびに、API(GET /api/results/{request_id}
)にリクエストを提出します。理想的には、タスクは今までに完了しており、タスクの結果と共に200 OKを返します。
しかし、ユーザーは強引であり、結果がまだ処理を完了していないときに、多くの熱心な更新が期待されます。
次のことを示すステータスコードの最良の選択肢は何ですか?
- このリクエストが存在する、
- まだ終わっていない、
- しかし、それも失敗していません。
単一のコードがすべてを通信することを期待していませんが、クライアントにコンテンツを期待させるのではなく、メタデータを渡すことができるものが欲しいのです。
202を返すことは理にかなっています。なぜなら、それはここでは他の意味を持たないからです。それはGET
要求であるため、おそらく「受け入れられる」ものは何もありません。それは合理的な選択でしょうか?
これらすべてに対する明白な代替手段-機能するが、ステータスコードの1つの目的を無効にする-は、常にメタデータを含めることです。
200 OK
{
status: "complete",
data: {
foo: "123"
}
}
...または...
200 OK
{
status: "pending"
}
次に、クライアント側で、リクエストが完了したかどうかを判断するためswitch
に(ため息をつきます)response.data.status
。
これは私がやるべきことですか?または、より良い代替手段はありますか?これは私にとってWeb 1.0だと感じています。
POST
リクエストを開いたままにしておきます。長いポーリングまたはWebソケットの主な問題は、ユーザーがブラウザーを閉じて戻ってくる可能性があることです。そのときにそれらを再び開くことができます(そしてそれは私がしていることです)が、それらのソケットを開く前に呼び出す単一のAPIを持っていることはきれいです。