APIまわりで出てくる「ジョブポーリング方式」は、ひとことで言うと、時間のかかる処理をいったん受け付けて、終わったかどうかをあとで確認しに行く方式です。
初心者の方が最初に引っかかりやすいのは、次の2点だと思います。
- なんでそんな回りくどいことをするのか
- その間、ページを離れられないのか
先に結論を書くと、重い処理を安全に扱うための設計であり、ページを離れてもジョブ自体はサーバー側で続けられるのが普通です。
ジョブポーリング方式とは?
通常のAPIは、リクエストを送るとすぐに結果を返します。
たとえば以下のような処理なら、1回のAPIで完結しやすいです。
- ユーザー情報を取得する
- 商品一覧を返す
- 設定を保存する
一方で、次のような処理は時間がかかります。
- AIで文章や画像を生成する
- 動画を変換する
- CSVやPDFを作る
- 大量データを集計する
こういう処理を1本のHTTP通信で最後まで待たせると、タイムアウトや画面待ちが起きやすくなります。
そこで使われるのがジョブポーリング方式です。
流れはシンプルです。
- クライアントが「この処理をお願いします」と送る
- サーバーは「受け付けました。job_id はこれです」とすぐ返す
- クライアントは一定間隔で「そのジョブ、終わりましたか?」と確認する
- サーバーは queued running succeeded failed などの状態を返す
- 完了したら結果を返す
なぜわざわざ分けるのか
理由は、HTTPの1往復だけで重い処理を抱え込まないためです。
もし動画変換に3分かかるのに、最初の POST に対して3分後まで返事をしないAPIだったら、現実にはかなり扱いにくいです。
- 通信が途中で切れやすい
- ブラウザやプロキシのタイムアウトに引っかかる
- ユーザー体験が悪い
- サーバー側も長い接続を抱え続ける
ジョブ化してしまえば、受付だけ先に返せます。これでAPIも画面もだいぶ安定します。
実際のイメージ
最小構成なら、だいたい次のようになります。
1. ジョブ受付
POST /reports
-> 202 Accepted
{
"job_id": "job_123",
"status": "queued"
}
ここで大事なのは、結果そのものではなく受付結果を返していることです。
2. 状態確認
GET /reports/job_123
-> 200 OK
{
"job_id": "job_123",
"status": "running",
"progress": 60
}
3. 完了
GET /reports/job_123
-> 200 OK
{
"job_id": "job_123",
"status": "succeeded",
"result_url": "https://example.com/reports/job_123.csv"
}
これが「ポーリング」です。
要するに、クライアント側が定期的に見に来るわけです。
ページを離れてもいいのか
ここは誤解されやすいですが、離れて大丈夫です。
ただし、「何が止まって何が止まらないか」を分けて考える必要があります。
止まらないもの:
- サーバー側で動いているジョブ
止まるもの:
- そのページ上で実行していたポーリング
つまり、ブラウザの画面を閉じた瞬間に確認処理は止まるけれど、本体の処理はサーバー側で続く、という形が一般的です。
あとでページに戻ってきたときに、以前の job_id を持っていれば、再度 GET /jobs/{job_id} を叩いて続きから状況確認できます。
実務ではよく、次のようにします。
- job_id をDBに保存する
- あるいは localStorage に保存する
- 再訪時に job_id を読み出してポーリングを再開する
なので、「ジョブポーリング方式だとページを離れられない」という理解は正確ではありません。
正しくは、ページを離れると監視は止まるが、ジョブは止まらないことが多い、です。
どんなAPIでよく使う?
以下のような「すぐ終わらない処理」でよく使われます。
- 画像生成API
- 音声文字起こしAPI
- レポート出力API
- バッチ集計API
- ファイル変換API
最近だとAI系APIとの相性がかなり良いです。
生成や解析に数十秒以上かかるなら、この設計が自然です。
メリット
- タイムアウトしにくい
- 進捗表示を入れやすい
- 再試行や失敗管理がしやすい
- 重い処理をAPIとして公開しやすい
デメリット
- クライアント実装が少し増える
- ポーリング間隔によっては無駄な通信が発生する
- 完了していても、次に見に行くまで気づけない
たとえば5秒おきに確認している場合、処理が終わっても最大5秒ほど気づくのが遅れます。
他の方式との違い
同期APIとの違い
同期APIは、1回のリクエストで結果まで返します。
すぐ終わる処理には向いていますが、重い処理には弱いです。
Webhookとの違い
Webhookは、処理が終わったタイミングでサーバー側から通知してくる方式です。
- ポーリング: クライアントが確認しに行く
- Webhook: サーバーが通知する
外部サービス連携ではWebhookが便利ですが、受け取り側のURL公開や署名検証が必要になり、少し難しくなります。
初心者向けの最初の設計としては、ポーリングのほうが理解しやすいです。
WebSocketやSSEとの違い
こちらはリアルタイム通知向けです。
進捗が細かく変わるアプリでは有効ですが、仕組みはやや重くなります。
「まず動くAPIを作る」段階なら、ジョブポーリング方式のほうが実装しやすいケースが多いです。
設計するときの基本ポイント
初心者のうちは、まずこのあたりを押さえれば十分です。
- 受付APIでは 202 Accepted を返す
- job_id を返す
- 状態は queued running succeeded failed くらいに絞る
- 完了時の結果取得方法を決める
- 失敗時の error_code や message を返す
- ポーリング間隔を短くしすぎない
ポーリング間隔は1秒固定より、2秒、4秒、8秒のように少しずつ間隔を広げるほうが実務では安定しやすいです。
これは「バックオフ」と呼ばれます。
まとめ
ジョブポーリング方式は、時間のかかる処理を安全にAPI化するための定番設計です。
ポイントは次の3つです。
- 受付と結果取得を分ける
- クライアントは job_id を使って定期確認する
- ページを離れても、ジョブ自体はサーバー側で継続できる
API初心者のうちは、まずこのイメージを持っておけば十分です。
「重い処理はその場で待たせず、仕事だけ受けて、終わったかをあとで見に行く」と覚えると理解しやすいです。