メインコンテンツまでスキップ

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

実装方針

  1. Gateway: Connect RPCを使用してHTTP/JSONを提供
  2. API Server: 内部はgRPCで通信
  3. Protocol Buffers: 両方で同じproto定義を使用
  4. 自動変換: 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層のオーバーヘッド)

関連ADR

参考