ADR-0002: Connect RPCによるHTTP/JSON API提供
ステータス
Accepted - 2024年採用
コンテキスト
Bazbiiでは、モバイルアプリとWebアプリケーションからアクセスするAPIを提供する必要がありました。 以下の要件がありました:
- フロントエンド対応: HTTP/JSON形式でアクセス可能にしたい
- 型安全性: Protocol Buffersで定義したコントラクトを活用したい
- 効率的な内部通信: バックエンド間はgRPCで効率的に通信したい
- 開発効率: プロトコル定義を一元管理したい
決定
Connect RPCを採用し、以下の構成を実現しました:
Client (Mobile/Web)
↓ HTTP/JSON
Gateway (Connect RPC)
↓ gRPC
API Server
↓
server-core
実装方針
- Gateway: Connect RPCを使用してHTTP/JSONを提供
- API Server: 内部はgRPCで通信
- Protocol Buffers: 両方で同じproto定義を使用
- 自動変換: GatewayでHTTP/JSON ↔ gRPCの変換を自動化
考慮した代替案
代替案1: REST API(手動実装)
- メリット:
- 広く理解されている
- 標準的なHTTPメソッドとステータスコード
- デメリット:
- Protocol Buffersの恩恵を受けにくい
- コード生成が難しい
- 型安全性が低い
- 判断: 型安全性と開発効率を優先し、却下
代替案2: GraphQL
- メリット:
- 柔軟なクエリ
- 型安全なスキーマ
- デメリット:
- 学習コストが高い
- 複雑な実装になりがち
- モバイルアプリの要件には過剰
- 判断: 要件に対して過剰な設計と判断し、却下
代替案3: gRPC-Web
- メリット:
- フロントエンドから直接gRPCを使用可能
- デメリット:
- ブラウザからの制限がある
- モバイルアプリでの利用が難しい
- 判断: プラットフォーム間の互換性を優先し、却下
影響
メリット
- ✅ 型安全性: Protocol Buffersによる型安全なAPI定義
- ✅ コード生成: サーバーとクライアントのコードを自動生成
- ✅ 一貫性: 内部(gRPC)と外部(HTTP/JSON)で同じコントラクトを使用
- ✅ 開発効率: Gatewayでの自動変換により、手動の変換コードが不要
- ✅ 後方互換性: Connect RPCは標準的なHTTP/JSONを提供
デメリット・課題
- ⚠️ 学習コスト: Connect RPCの理解が必要
- ⚠️ Gateway層の追加: 追加のコンポーネントが必要
- ⚠️ デバッグの複雑さ: 2層構造により、トラブルシューティングがやや複雑
運用上の考慮事項
- Gatewayのスケーリング戦略
- エラーハンドリングの一貫性
- レイテンシの監視(Gateway層のオーバーヘッド)