Python で Web サービスや API を開発するとき、通信技術の選択は設計の根幹に関わります。REST、WebSocket、gRPC、MQTT……名前は聞いたことがあっても、「自分のプロジェクトにはどれが合うのか?」が分からないまま選んでしまうケースは少なくありません。
この記事では、Python で実際に使われる 8 つの通信技術を用途・難易度・速度・リアルタイム対応の軸で比較し、それぞれの実装例とともに「どんな場面で選ぶべきか」を整理します。
8 技術の比較一覧
| 技術 | 主な用途 | 難易度 | 速度 | リアルタイム | 特徴 |
|---|---|---|---|---|---|
| REST | API 全般 | 低 | 普通 | × | Web API の標準 |
| WebSocket | リアルタイム通信 | 中 | 高 | ◎ | 双方向・常時接続 |
| gRPC | 内部マイクロサービス | 高 | ◎ | ○ | Protocol Buffers |
| MQTT | IoT・センサー | 中 | 高 | ○ | 超軽量 Pub/Sub |
| SSE | サーバー→クライアント通知 | 低 | 普通 | ○ | 片方向ストリーム |
| Celery | 非同期バックグラウンド処理 | 中 | 高 | × | タスクキュー |
| requests | HTTP クライアント | 低 | 普通 | × | 同期・シンプル |
| aiohttp | 非同期 HTTP クライアント | 中 | 高 | × | asyncio 対応 |
ポイントは「速そうだから」「新しいから」ではなく、プロジェクトの要件に合った技術を選ぶことです。9 割のプロジェクトは REST だけで十分ですし、リアルタイム性が必要なら WebSocket、IoT なら MQTT と、用途が決まれば選択肢は自然に絞られます。
REST ― Web API の標準
REST(Representational State Transfer)は、HTTP メソッド(GET / POST / PUT / DELETE)を使ってリソースを操作する、もっとも広く使われている API 設計スタイルです。「迷ったら REST」が実務での鉄則です。
Python では FastAPI が現在のデファクトスタンダードです。型ヒントベースの自動バリデーション、自動ドキュメント生成(Swagger UI)、非同期対応と、REST API に必要な機能がワンパッケージで揃います。
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id, "name": "Alice"}
# GET /users/1 → {"user_id": 1, "name": "Alice"}
いつ使う?
- Web API の公開(外部向け・内部向け問わず)
- CRUD 操作(データの作成・取得・更新・削除)
- 管理画面のバックエンド
- モバイルアプリのサーバーサイド
FastAPI は自動で /docs に Swagger UI を生成します。これだけで API ドキュメントの 8 割が片付くため、ドキュメント作成コストが激減します。また、Flask から移行する場合もルーティングの記法が似ているため、学習コストは低いです。
REST はリクエスト/レスポンスの「一往復」が基本です。チャットのように「サーバーからクライアントに随時データを送りたい」場合は REST では実現できません。ポーリング(定期的にリクエストを送る)で無理やり実装すると、サーバー負荷とレイテンシが跳ね上がります。
pip install fastapi uvicorn
WebSocket ― 双方向リアルタイム通信
WebSocket は、クライアントとサーバー間で常時接続の双方向通信チャネルを確立するプロトコルです。HTTP とは異なり、一度接続すればサーバーからもクライアントからも自由にデータを送信できます。
FastAPI は WebSocket もネイティブにサポートしているため、REST API と同じプロジェクト内で WebSocket エンドポイントを追加できます。
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(ws: WebSocket):
await ws.accept()
while True:
data = await ws.receive_text()
await ws.send_text(f"Echo: {data}")
いつ使う?
- チャットアプリケーション
- リアルタイムダッシュボード(株価、監視画面)
- オンラインゲームの状態同期
- 共同編集(Google Docs のような仕組み)
WebSocket は「接続を維持し続ける」ため、クライアント数が増えるとサーバーのメモリ消費が線形に増加します。数千〜数万の同時接続が見込まれる場合は、Redis Pub/Sub と組み合わせてスケールアウトする設計が必要です。
「とりあえず WebSocket」で全 API を実装してしまう初心者がいますが、通常のデータ取得には REST の方が圧倒的にシンプルで、キャッシュやロードバランサーとの相性も良いです。WebSocket は本当にリアルタイム性が必要な部分だけに限定しましょう。
pip install fastapi uvicorn
gRPC ― 高速マイクロサービス通信
gRPC は Google が開発した RPC(Remote Procedure Call)フレームワークです。データのシリアライズに Protocol Buffers(protobuf) を使い、JSON ベースの REST と比べて通信量が小さく、処理速度も高速です。
通信インターフェースを .proto ファイルで定義し、そこからクライアント・サーバーのコードを自動生成する仕組みです。型安全が保証されるため、大規模なマイクロサービス間通信で威力を発揮します。
# greeter.proto で定義したサービスを利用
import grpc
import greeter_pb2
import greeter_pb2_grpc
channel = grpc.insecure_channel('localhost:50051')
stub = greeter_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(greeter_pb2.HelloRequest(name='World'))
print(response.message) # Hello, World!
いつ使う?
- マイクロサービス間の内部通信
- レイテンシが重要な高負荷システム
- 多言語環境(Python ↔ Go ↔ Java 間の通信など)
- ストリーミング通信が必要な場面
gRPC は HTTP/2 上で動作し、1 つの TCP 接続上で複数のリクエストを並列処理(多重化)できます。REST + HTTP/1.1 では接続数がボトルネックになる高負荷環境で、大きな性能差が出ます。
gRPC はブラウザから直接呼べません(gRPC-Web というプロキシ層が必要)。外部公開 API には REST を使い、gRPC は内部通信に限定するのが定石です。また、.proto ファイルの管理と protobuf のコード生成が必要なため、小規模プロジェクトでは導入コストが見合わないことが多いです。
pip install grpcio grpcio-tools
MQTT ― IoT のための軽量プロトコル
MQTT(Message Queuing Telemetry Transport)は、帯域幅が制限された環境向けに設計された超軽量な Pub/Sub(発行/購読)型メッセージプロトコルです。TCP 上で動作し、ヘッダーはわずか 2 バイトから。
「ブローカー」と呼ばれる中継サーバーを介して、パブリッシャー(送信側)がトピックにメッセージを発行し、サブスクライバー(受信側)がそのトピックを購読する仕組みです。
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print(f"Connected (rc={rc})")
client.subscribe("sensor/temperature")
def on_message(client, userdata, msg):
print(f"{msg.topic}: {msg.payload.decode()}")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.hivemq.com", 1883)
client.loop_forever()
いつ使う?
- IoT デバイスのセンサーデータ収集
- ロボットの遠隔制御・状態監視
- スマートホーム機器の連携
- 工場の設備モニタリング
MQTT には QoS(Quality of Service)レベルが 3 段階あります。QoS 0 は「送りっぱなし」(最速だが届かない可能性あり)、QoS 1 は「最低 1 回配達」、QoS 2 は「正確に 1 回配達」。センサーデータのように多少欠けても問題ないなら QoS 0、制御コマンドなら QoS 1 以上を選びましょう。
MQTT は Web アプリの汎用通信には向いていません。ブラウザから使う場合は MQTT over WebSocket が必要で、一般的な Web API なら REST や WebSocket の方が素直です。
pip install paho-mqtt
SSE ― サーバーからの片方向ストリーム
SSE(Server-Sent Events)は、サーバーからクライアントへの一方通行のリアルタイム通信です。HTTP 上で動作し、WebSocket のような独自プロトコルではないため、プロキシやファイアウォールとの互換性が高いのが利点です。
「サーバーが一方的に通知を送り続ける」シナリオ ―― ログのストリーミング、通知フィード、進捗状況の表示 ―― に最適です。
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import asyncio
app = FastAPI()
async def event_generator():
for i in range(10):
yield f"data: Event {i}\n\n"
await asyncio.sleep(1)
@app.get("/stream")
async def stream():
return StreamingResponse(
event_generator(),
media_type="text/event-stream"
)
いつ使う?
- 通知フィード(新着メッセージ、アラート)
- ログのリアルタイム表示
- 長時間処理の進捗バー
- AI チャットのストリーミングレスポンス(ChatGPT のような逐次表示)
SSE はブラウザ側の実装が EventSource API だけで済むため、フロントエンドの実装コストが WebSocket より圧倒的に低いです。「サーバー → クライアント」の片方向で十分なら、WebSocket ではなく SSE を選ぶ方がシンプルです。
SSE は「クライアント → サーバー」の通信ができません。双方向が必要なら WebSocket を使ってください。また、HTTP/1.1 ではブラウザの同一ドメインへの同時接続数に制限(通常 6 本)があるため、SSE 接続が 1 つ分を消費する点に注意が必要です。
pip install fastapi uvicorn
Celery ― バックグラウンドタスクキュー
Celery は、重い処理をバックグラウンドで非同期実行するためのタスクキューシステムです。Web リクエスト中に時間のかかる処理(メール送信、画像リサイズ、データ集計など)を同期的に行うとレスポンスが遅くなりますが、Celery に投げればリクエストは即座に返却され、処理はバックグラウンドで進行します。
メッセージブローカー(Redis または RabbitMQ)を介してタスクをキューイングする仕組みです。
from celery import Celery
app = Celery('tasks', broker='redis://localhost:6379/0')
@app.task
def send_welcome_email(user_id: int):
# 重い処理(メール送信、外部API呼び出し等)
print(f"Sending email to user {user_id}")
return True
# 呼び出し側: send_welcome_email.delay(42)
いつ使う?
- メール・通知の非同期送信
- 画像・動画の変換処理
- 定期バッチ処理(celery beat)
- レポート生成、データエクスポート
Celery は「定期実行」もサポートしています。celery beat を使えば、cron のようにスケジュールされたタスクを Python コード内で管理できます。「毎日 3 時にレポートを生成」といった処理を、サーバーの crontab ではなくアプリケーションコードとして管理できるのは大きな利点です。
Celery を使うには Redis(または RabbitMQ)が別途必要です。つまり、インフラの運用コストが増えます。「1 日に数件のメール送信」程度なら、FastAPI の BackgroundTasks で十分です。Celery は「タスク量が多い」「失敗時のリトライが必要」「ワーカーのスケールアウトが必要」といった要件が出てから導入しましょう。
pip install celery redis
requests ― もっともシンプルな HTTP クライアント
requests は Python で HTTP 通信を行うための定番ライブラリです。外部 API の呼び出し、Web スクレイピング、テストでの API 確認など、「Python から HTTP リクエストを送る」場面では真っ先に選ばれます。
その最大の魅力は圧倒的なシンプルさ。3 行で HTTP GET が完結します。
import requests
response = requests.get("https://api.github.com/users/python")
print(response.status_code) # 200
print(response.json()["name"]) # Python
いつ使う?
- 外部 API の呼び出し(REST API クライアント)
- Web スクレイピングの HTTP 取得部分
- 開発中の API テスト
- CLI ツールからの HTTP リクエスト
requests.Session() を使うと、Cookie やヘッダーを複数リクエスト間で共有でき、TCP 接続の再利用も行われるため、同じサーバーへの連続リクエストが高速化します。認証付き API を叩く場合は Session を使いましょう。
requests は同期ライブラリです。100 件の API を順番に呼ぶと、1 件 0.5 秒なら合計 50 秒かかります。大量の HTTP リクエストを並列に送りたい場合は、次に紹介する aiohttp を使ってください。
pip install requests
aiohttp ― 非同期 HTTP クライアント
aiohttp は asyncio ベースの非同期 HTTP クライアント/サーバーライブラリです。requests の非同期版と考えると分かりやすいでしょう。大量の HTTP リクエストを並行に送信できるため、API クローラーや並列データ取得で圧倒的なスループットを発揮します。
import aiohttp
import asyncio
async def fetch(url: str) -> int:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return response.status
async def main():
urls = ["https://api.github.com"] * 10
tasks = [fetch(url) for url in urls]
results = await asyncio.gather(*tasks)
print(results) # [200, 200, 200, ...]
asyncio.run(main())
いつ使う?
- 大量の外部 API 呼び出し(数百〜数千件の並列リクエスト)
- Web クローラー・スクレイパー
- 既に asyncio を使っているプロジェクト
- 非同期 Web サーバーの構築
asyncio.gather() と組み合わせると、10 件のリクエストを「ほぼ同時に」送信できます。requests で 50 秒かかる処理が aiohttp なら数秒で完了する ―― これが非同期の威力です。ただし、相手サーバーのレート制限には注意しましょう(asyncio.Semaphore で同時接続数を制御できます)。
async/await の概念を理解していないまま使うと、混乱のもとになります。まず requests で同期的な HTTP 通信に慣れてから、必要性が出たタイミングで aiohttp に移行するのが堅実です。
pip install aiohttp
技術選択ガイド + 実務構成パターン
ここまで 8 つの技術を見てきました。実務では「1 つだけ選ぶ」のではなく、組み合わせて使うのが普通です。以下に、プロジェクト規模別の定番構成を示します。
| 規模 | 構成 | 例 |
|---|---|---|
| 個人/小規模 | FastAPI (REST) | ツールサイトの API、個人ブログの CMS |
| リアルタイム込み | FastAPI (REST + WebSocket) | チャット付きサービス、ダッシュボード |
| 中規模 | FastAPI (REST) + Celery + Redis | EC サイト、SaaS |
| 大規模 | FastAPI (REST) + gRPC (内部) + Celery | マイクロサービス基盤 |
| IoT | MQTT + REST (管理画面) | センサーネットワーク、スマートホーム |
初心者が陥りやすい失敗パターン:
- 全部 WebSocket で作る → REST で十分な部分まで WebSocket にすると、キャッシュが効かず、デバッグも困難になる
- 最初から gRPC を選ぶ → 小規模なうちは REST で十分。gRPC の恩恵が出るのはサービス間通信が複雑化してから
- async を理解せず aiohttp を使う →
requestsで困っていないなら無理に移行しない - Celery を過剰導入する → 数件のバックグラウンドタスクなら FastAPI の
BackgroundTasksで十分
共通するのは「技術を選びすぎる問題」です。シンプルに始めて、本当に必要になったら追加する ―― これが実務で最も成功率の高いアプローチです。
まとめ
Python の Web 通信技術は、用途で選べば迷いません。
- API 全般 → REST(FastAPI)
- リアルタイム双方向 → WebSocket
- 内部高速通信 → gRPC
- IoT・センサー → MQTT
- サーバー通知 → SSE
- バックグラウンド処理 → Celery
- HTTP クライアント(同期) → requests
- HTTP クライアント(非同期) → aiohttp
迷ったらREST から始めるのが安全です。ほとんどのプロジェクトは REST だけで立ち上がりますし、必要に応じて WebSocket や Celery を後から足すのは難しくありません。技術選定は「足りなくなったら足す」くらいがちょうど良いのです。

コメントを残す