🧩 概要
この記事では、複数のコンテナを連携させるWebアプリケーション構成において、サービス間通信をHTTPで行う仕組みを整理し、なぜ1つのAPIエンドポイントだけでデータのやりとりが成立するのかを具体的に解説します。
- コンテナ間の通信はどうなっているの?
- なぜ
POST /generate_somethingだけで成立するの? - Dockerネットワーク上での名前解決やCORSはどう処理するの?
といった疑問に答える内容です。
🧱 システム構成(抽象化)
[Browser]
↓ HTTP (Fetch)
[Frontend: React+Vite] (port:5173)
↓ HTTP (POST)
[AI API: FastAPI + LLM] (port:8005)
↓ SDK
[LLM Provider API (e.g. Bedrock)]
- フロントエンド:ユーザー入力の収集とUI表示
- AI API:HTTPリクエストを受け、AI処理を行って結果を返却
- LLM Provider:生成AIの実行基盤(外部API)
🔁 通信フローの解説
📤 フロントエンド → AI API(HTTP POST)
await fetch("http://localhost:8005/generate_something", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
answers: {
"1": "週末に山に登った",
"2": "リフレッシュできた"
}
})
});
- ブラウザ上のReactアプリが、HTTP POSTでAPIを呼び出します
- JSON形式の入力を、AI APIに一括送信します
🧠 AI API → LLMプロバイダ(SDK経由)
- FastAPIがPOSTされたデータを受け取ります
- SDK(例:LangChainやboto3など)を通じて、外部のLLM APIを呼び出します
- プロンプトとして渡し、生成結果(テキストやMarkdown)を取得します
📥 結果の返却と表示
- AI APIは、生成された結果をJSONで返却します
- フロントエンドはそれを受け取り、画面にレンダリングして表示します
❓ なぜ POST /generate_something だけで成り立つのか?
✅ ステートレスなAPI設計
- AI APIは、状態(履歴・ユーザー情報)を一切保持しない
- ユーザーの入力内容すべてを、フロントエンド側が持ち、まとめてPOSTしている
- サーバー側は「入力 → 生成 → 返却」を一発で処理するだけのシンプル構造
✅ フロントエンド主導の状態管理
- チャットや回答の履歴は、すべてクライアント側で
useStateやZustandなどで保持 - サーバーに「履歴を問い合わせる」必要がないため、GET APIは不要
🌐 Docker環境での通信の仕組み
🐳 サービス名で通信できる
Docker Composeの内部ネットワークでは、サービス名がDNSのように解決されます:
services:
frontend:
build: ./frontend
ports:
- "5173:5173"
ai:
build: ./ai
ports:
- "8005:8005"
→ frontend から http://ai:8000/generate_something にアクセスできる
🔓 CORSの許可
FastAPIでは以下のように CORSMiddleware を設定することで、ブラウザからのアクセスを許可します:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
🔐 AWS認証情報の管理(参考)
AI APIが外部のLLMプロバイダ(例:AWS Bedrock)とやりとりする際、認証情報は .env で管理され、Dockerに以下のように渡されます:
services:
ai:
env_file:
- .env
🧩 補足:将来的に必要になるかもしれないエンドポイント
| メソッド | エンドポイント | 用途 |
|---|---|---|
GET /history |
チャット履歴を取得 | |
POST /chat |
メッセージを1つずつ送る | |
DELETE /history |
履歴をリセットする | |
POST /session/reset |
セッションを初期化する |
今はフロントが全ての状態を持っているので不要ですが、拡張時には検討価値ありです。
✅ まとめ
- コンテナ間通信は HTTP が基本で、Docker内ではサービス名で名前解決できる
- シンプルな POST API だけで成り立つのは「状態をサーバーに持たせない設計」だから
- フロントエンドがチャットや履歴の状態を完全に管理しているため、サーバーは stateless に単発処理だけで済む
- 本構成は拡張・疎結合にも強く、マルチリポジトリ・マイクロサービスとの親和性が高い
✍️ おまけ
このような構成は、AI処理を含むプロダクトのPoCやMVP段階で非常に相性が良く、最初の設計としておすすめです。将来的に認証・ログ保存・セッション管理などが必要になったら、APIを段階的に増やしていくことで、柔軟にスケールできます。