第1章 Web API と非同期アーキテクチャの全体像
Web アプリケーションやスマートフォンアプリは、インターネットを通じてサーバーとデータをやり取りします。その中心的な役割を果たすのが Web API サーバーです。
本章では、Web API の基本的な仕組み、従来の同期通信とモダンな非同期通信の違い、そして FastAPI、Uvicorn、Celery、Redis を組み合わせた全体アーキテクチャを学びます。
1.1 Web API とクライアント・サーバーの関係
Web API(Application Programming Interface)は、プログラム同士がネットワーク経由でデータを受け渡すための約束事です。
ブラウザやスマートフォンなどのクライアントは、HTTP リクエストをサーバーに送信します。サーバーはその要求を処理し、JSON 形式などのデータを HTTP レスポンスとして返却します。ユーザーの画面表示とサーバーのデータ処理を分離できるため、柔軟なシステム開発が可能になります。
1.2 同期処理(WSGI)と非同期処理(ASGI)
従来の Python Web アプリケーションでは、WSGI(Web Server Gateway Interface)という標準規格が使われていました。
WSGI は 1 つのリクエストを 1 つのスレッドやプロセスが専有して処理する「同期型」です。データベースへの問い合わせや外部 API 通信など、通信の待ち時間(I/O 待ち)が発生している間もプロセスが塞がってしまい、大量の同時接続を処理するには限界がありました。
一方、ASGI(Asynchronous Server Gateway Interface)は「非同期処理(async / await)」に対応した新しい規格です。通信の待ち時間が発生した際に、別のリクエストの処理へ CPU を切り替えることができるため、少ないリソースで数万規模の同時アクセスを効率よく処理できます。
graph TD
subgraph WSGI["同期型 (WSGI)"]
W_Req["リクエスト 1"] --> W_Wait["I/O 待ち (CPU 占有)"] --> W_Res["レスポンス 1"]
W_Req2["リクエスト 2"] --> W_Block["待機 (前の処理が終わるまで待つ)"]
end
subgraph ASGI["非同期型 (ASGI)"]
A_Req1["リクエスト 1"] --> A_Wait["I/O 待ち発生"]
A_Wait -.->|"待ち時間に切り替え"| A_Req2["リクエスト 2 の処理開始"]
end
1.3 FastAPI・Uvicorn・Celery・Redis の役割分担
高速で安定した Web サービスを構築するために、それぞれの得意分野に応じたコンポーネントを組み合わせて使用します。
-
Uvicorn: ASGI に準拠した Web サーバーです。クライアントからの HTTP 接続を直接受け付け、高速な非同期イベントループで FastAPI にリクエストを渡します。
-
FastAPI: Python の型ヒントを駆使した最新の Web フレームワークです。URL ルーティング、リクエストの型検証、レスポンスの生成、API 仕様書(Swagger UI)の自動生成を担当します。
-
Redis: メモリ上でデータを高速に保持するインメモリデータストアです。ここでは非同期タスクの待ち行列を管理する「メッセージブローカー」および結果の保存先として利用します。
-
Celery: 時間のかかる重い処理をバックグラウンドで非同期に実行する「分散タスクキュー」です。API サーバーとは別の独立したプロセス(ワーカー)として動作します。
1.4 システム全体のデータフローと構成図
ユーザーがアクセスしたときの全体の流れを整理します。
- クライアントが Uvicorn へ HTTP リクエストを送信します。
- Uvicorn がリクエストを FastAPI アプリケーションに渡します。
- 数秒以内に完了する軽量なデータ取得や更新は、FastAPI がそのまま処理して即座に応答します。
- 画像変換や一括メール送信、機械学習推論など数秒以上かかる重い処理は、FastAPI が Redis にタスクを投入し、タスク ID のみをクライアントに即座に返却します。
- 裏で待機している Celery ワーカーが Redis からタスクを取り出して実行し、完了結果を Redis に保存します。
sequenceDiagram
autonumber
actor Client as クライアント
participant Uvicorn as Uvicorn (ASGI サーバー)
participant FastAPI as FastAPI (API アプリ)
participant Redis as Redis (Broker / Backend)
participant Celery as Celery (ワーカー)
Client->>Uvicorn: HTTP POST /tasks (重い処理依頼)
Uvicorn->>FastAPI: リクエスト転送
FastAPI->>Redis: タスクを登録 (タスク ID 発行)
FastAPI-->>Client: 202 Accepted (タスク ID を即座に返却)
par バックグラウンド実行
Redis->>Celery: タスクを通知
Celery->>Celery: 重い処理を実行
Celery->>Redis: 実行結果を保存
end
Client->>FastAPI: HTTP GET /tasks/{task_id} (進捗確認)
FastAPI->>Redis: 状態・結果を問い合わせ
FastAPI-->>Client: 200 OK (進捗 or 完了結果)