Upgrade to Pro — share decks privately, control downloads, hide ads and more …

FastAPIの魔法をgRPC/Connect RPCへ

Avatar for MonotaRO MonotaRO PRO
September 28, 2025

FastAPIの魔法をgRPC/Connect RPCへ

PyCon JP 2025の登壇資料です。

Avatar for MonotaRO

MonotaRO PRO

September 28, 2025
Tweet

More Decks by MonotaRO

Other Decks in Technology

Transcript

  1. 自己紹介 伊藤 泰 (Yasushi Itoh) 📍 所属: MonotaRO プラットフォームエンジニアリング部門 デベロッパーインターフェースグルー

    プ 兼 CTO室 戦略チーム 🔗 役割: 現場と基盤の「橋渡し役」 🚀 現職: MonotaROでプラットフォームエンジニアリング 📈 経歴: 富士ゼロックス → メルカリ → MonotaRO 📈 Python OSS活動: 本日ご紹介するライブラリ: github.com/i2y/pydantic-rpc Connect RPC実装: github.com/Connect RPC/connect-python クロスプラットフォームUIフレームワーク: github.com/i2y/castella Python VM上のプログラミング言語: github.com/i2y/mochi など
  2. APIとは? — RESTとRPC、それぞれのスタイル 🔌 API:ソフトウェア間の「窓口」 API(Application Programming Interface)は、あるソフトウェアの機能やデータを、 別のソフトウェアから呼び出して利用するための「窓口」や「接 点」を指す広い概念

    🍳 レストランのメニューがAPIにあたります 客(ソフトウェア)はメニューを見て、厨房(別のソフトウェア)に注文(リクエスト)を出し、 料理(データや機能)を受け取ります このAPIという目的を達成するために、 いくつかの代表的な「手段(設計スタイル)」があります
  3. Web API — 本発表で扱うAPIの範囲 💡 本発表では以後、API = Web APIのことを指しています 🌐

    Web API:インターネット経由でアクセス可能なAPI Web APIは、HTTP/HTTPSプロトコルを使用してインターネット経由でアクセス可能なAPIです。 Webアプリケーション、モバイルアプリ、サーバー間通信などで広く使用されています。 📡 技術的特徴 HTTP/HTTPSプロトコルを使用 JSON、XMLでデータをやり取り インターネット経由でアクセス ブラウザからもアクセス可能 🔧 具体例 Twitter API(ツイート投稿・取得) Google Maps API(地図表示) GitHub API(リポジトリ操作) OpenAI API(AI機能利用) このWeb APIを実現するための 代表的な「設計スタイル」を見ていきましょう
  4. スタイル① REST:「モノ」を指さして注文 REST(Representational State Transfer) 現在最も広く採用されている「リソース(モノ)」中心の考え方 🍳 考え方 メニューにある「広島風お好み焼き(そば入り)」というモノ(名詞)を 指さし、

    「これを一枚ください」と注文するイメージ 🔧 技術的な特徴 全ての情報を「リソース」として扱い、一意のURL(/users/123)で 識別 HTTPメソッド(GET, POST, PUT, DELETE)でリソースを操作 ステートレスな通信が原則 ✅ 向いている用途: Webの仕組みと親和性が高く、柔軟で拡張性の高いシステム、特に公開APIなどに最適
  5. スタイル② RPC:「アクション」を直接指示 RPC(Remote Procedure Call) 遠隔にある手続きを呼び出す、具体的な「アクション(動詞)」中心のスタイル ☎️ 考え方 厨房に「内線電話」をかけ、 「お好み焼きを焼いてくれ!」と具体的なアクション(動詞)で

    直接指示を出すイメージ 🔧 技術的な特徴 getUser や createUser のように、関数名を直接指定して呼び出し データ転送量が少なく、高速に動作する傾向 代表例:gRPC, Connect RPC, Thrift ✅ 向いている用途: サービス間の内部通信など、パフォーマンスが重視される場面で強みを発揮
  6. APIとは? — まとめ 🍽️ REST メニューの「モノ」を指さして注文 リソース(モノ)中心の考え方 URL(/users/123)で識別 HTTPメソッド(GET, POST,

    PUT, DELETE) ステートレスな通信 GET /api/users/123 📞 RPC 厨房に「アクション」を直接指示 アクション(動詞)中心の考え方 関数名を直接指定 バイナリ形式で高速通信 gRPC, Connect, Thriftなど getUserById(123) 💡 実は境界線は曖昧: RPCでもリソース指向の設計は可能です。C言語でもオブジェクト指向的なプログラミングができるように、 RESTfulなリソース指向なRPCをも存在します。 (参考:Google AIP - google.aip.dev)
  7. 分散/マイクロサービスアーキテクチャの課題 マイクロサービスアーキテクチャに代表されるアプリケーションを複数のサービスに分割して連携させる分散アーキテクチャでは、 サービス間通信が重要です。Web APIによる通信を採用した場合、いくつかの課題が生じることがあります。 🐢 ① 通信のオーバーヘッドとパフォーマンス 一つの処理を実行するために、内部で複数のサービスをAPIで呼び出すこ とが頻繁に起こります 例:

    商品購入 = 「認証」+「在庫確認」+「決済」... N+サービス間の通 信で レイテンシがN倍になることも 🕸️ ② サービスの複雑性と管理 サービスの数が増えると、どのサービスがどのサービスを呼び出している のか、まるでクモの巣のように複雑に絡み合います 影響: API仕様変更の影響範囲が不明。 依存関係がクモの巣状態でバージョン管理が困難 🔥 ③ 障害の連鎖(カスケード障害) 一つのサービスがダウンすると、そのサービスを呼び出していた別のサー ビスもエラーになり、さらにそのサービスを… 結果: 障害がドミノ倒しのように連鎖。 システム全体がダウンすることも。「耐障害性」の設計が必須 🕵️ ④ 可観測性(Observability)の低下 システム全体で何が起きているのかを把握することが難しくなります 課題: エラーの根本原因が不明。数十サービスのどこが問題? 分散トレーシングなどの仕組みが必須に
  8. 課題解決に型駆動API技術が役立つ ✨ 開発が楽になり、ミスが激減 gRPCなどでは.protoファイルのような「契約書」からプログラムの雛形 を自動生成。エディタが入力補完。 FastAPIでも: age: int と書くだけで自動バリデーション 🚀

    無駄がなく、高速な通信 やり取りするデータの形式が厳密に決まり、通信を最適化。 gRPC/Connect RPC: Protobufで通信量を削減 🛡️ システムが頑健になる 契約違反のデータは自動的に弾かれ、障害の連鎖を防止。 FastAPI: 422 Unprocessable Entityを自動返却 🔍 システムの可観測性向上 厳格な「契約」が通信経路の明確な「地図」となる。 gRPC: UserService/CreateUserのような具体的なトレース
  9. 型駆動API開発の分類 これまでの説明でもすでに触れていましたが、型駆動(スキーマ駆動)のAPI開発は2種類に大別できます。 📜 スキーマファースト gRPC/Connect RPC .protoファイルが絶対的な「憲法」 プログラムコードはこの憲法に従う 言語中立でコード生成 message

    User { int32 id = 1; string name = 2; } 🐍 コードファースト FastAPI Pythonコードが全ての源泉 スキーマはコードを反映した結果 Python開発者に最適化 class User(BaseModel): id: int name: str @app.post("/users") def create_user(user: User):
  10. 型駆動API技術による開発の分類 📜 gRPC/Connect RPC: スキーマファースト 「スキーマファースト」のアプローチ。まず初めに、言語から独立した.protoという設計図(スキーマファイル)を定義し、 その設計図から各言語のサーバーやクライアントのコードを自動生成する方式 ⚖️ 契約が絶対 .protoファイルが絶対的な「憲法」

    プログラムコードはこの憲法に従うしかなく、 開発者が勝手に変更することはできない 🌐 言語中立 Goで書かれたサーバーと、PythonやTypeScriptで 書かれたクライアントが、寸分違わず 同じ契約を共有できることが保証される 「契約(スキーマ)がコードを生成する」という点が、gRPC/Connect RPCの強み
  11. FastAPI: コードファースト 🐍 FastAPI: コードファースト 「コードファースト」のアプローチ。まずPythonのコード(Pydanticモデル)を書き、 そのコードを元にAPIの仕様書であるOpenAPIスキーマが後から自動生成される 👑 コードが主役 Pythonコードが全ての源泉

    スキーマ(APIドキュメント)は、 あくまでコードを反映した結果に過ぎない 🚀 エコシステムへの最適化 Python開発者は別のスキーマ言語を学ぶ必要なし .protoファイル作成やスタブ生成の手間が省ける 開発の初期段階での障壁が低い 多言語環境で厳密な規約を強制したい → gRPC/Connect RPC Python中心で迅速に堅牢なAPI構築 → FastAPI
  12. 💡 アイデア:二つのアプローチの融合 🤔 二者択一である必要はあるのか? gRPC/Connect RPCでもコードファーストで開発し、そこから.protoファイルを生成できれば、 二つのアプローチの「いいとこ取り」ができるかもしれません 🚀 ハイブリッドな開発スタイル 1.

    Pythonでコードファーストに書き、gRPC/Connect RPCのサービスを動かす 2. 必要に応じて.protoファイルをエクスポート 3. 多言語向けのクライアントやサーバーのスタブ生成に利用 これを実現するのが PydanticRPC
  13. ライブコーディング:PydanticRPC github.com/i2y/pydantic-rpc ① おなじみのPydanticモデル定義 from typing import Optional, List, Dict

    from pydantic_rpc import Message # Messageはpydantic.BaseModelのただのエイリアス class User(Message): # classs User(BaseModel) でも良い """ユーザー情報""" id: int name: str email: str class Task(Message):
  14. ③ 実行して動作確認 1️⃣ サーバーを起動 # サーバーを起動 uvicorn main:app --port 50051

    2️⃣ Connect プロトコルでRPCを呼び出す buf curl --protocol connect \ -d '{"name": "Taro Yamada", "email": "[email protected]"}' \ http://127.0.0.1:50051/task.v1.TaskService/CreateUser 3️⃣ レスポンス { "user": { "id": 1, "name": "Taro Yamada", "email": "[email protected]" } }
  15. PydanticRPCの処理フロー 開発者: サービスクラスとPydanticモデル定義とサーバー起動 ↓ PydanticRPC: 型解析エンジン・動的.proto生成 ↓ PydanticRPC: スタブコード生成 grpcio-tools

    (protoc)、protocプラグイン (connect-rpc, grpc) ↓ PydanticRPC: スタブコードとユーザー定義サービスクラス/モデルとの紐付け ↓ PydanticRPC: リクエスト受付開始/通信ライブラリ層 Connecpy/connect-python + grpcio ↓ gRPC/Connect RPCプロトコル 💡 ポイント: .protoファイルを書かずに、実行時に動的生成・スタブコード生成
  16. 型安全性がもたらす開発者体験 💻 IDEによる強力なサポート コードエディタがリクエスト/レスポンスの属性を自動補完 存在しない属性へのアクセスを実行前に検知 ✅ 静的型チェックの恩恵 mypyでクライアント・サーバー間のデータ型を検証 コンパイル時にバグを未然に防止 🔄

    安全なリファクタリング フィールド名変更時も、IDEの支援で全参照箇所を一括修正 型の変更が影響範囲を明確に示す 📚 コードがドキュメント Pydanticモデル定義そのものが正確な仕様書 型情報から自動でドキュメント生成可能 FastAPIと同様の高い開発者体験(DX)をgRPC/Connect RPCでも実現
  17. 実践での使い分け:判断基準 PydanticRPCの位置付け:gRPC/Connect RPCを、FastAPIのようなコードファーストの開発体験で実現 従って、開発体験にそんなに差がないのであれば、プロトコル、ここでは分かりやすく、FastAPI(RESET)と gRPC/Connect RPC をどう使い分ければ良いかがより本質的な問いに。 観点 FastAPI (REST)

    gRPC/Connect RPC 主な用途 Webフロントエンド向けAPI、公開API 内部マイクロサービス、高性能通信 データ形式 JSON(人間が読みやすい) Protobuf(バイナリ)・JSON(Connect) パフォーマンス gRPCよりはオーバーヘッド大 高効率・低レイテンシ ブラウザ対応 標準で対応 gRPC-WebやConnect RPCが必要 ストリーミング 限定的(SSEなど) 双方向ストリーミング
  18. モノタロウについて 🏭 日本最大級のBtoB ECプラットフォーム 間接消費資材(MRO:Maintenance, Repair and Operations)のECサイトを運営 工具・事務用品など2,400万点以上の商品を取り扱い、製造業・建設業などの事業者をサポート 📈

    事業規模 取扱商品数: 2,400万点以上 ユーザー数: 1,014万人 継続的な成長を実現 ⚙️ 技術的挑戦 モノリスを中心としたシステムから 変更容易性確保可能な、より分散疎結合なマイクロサービス的/イベント 駆動なアーキテクチャへの移行中 Python/Go/TypeScript/VB.NETなどによる 多言語開発環境 巨大ECの技術基盤を支えるアーキテクチャ Python/Go/TypeScriptによるポリグロット開発環境
  19. モノタロウ社内のFastAPI(REST)とRPCの使い分け実例 MonotaROでは、巨大なモノリスシステムをマイクロサービスなどへ分割するプロジェクトが進行中 開発環境は多言語(Python, Go, Swift, Kotlin, VB.NET など)にまたがっています 例① 販売価格サービス

    様々なクライアント(ECサイト関連他マイクロサービス など) → Connect RPC → 販売価格サービ ス → DB(Cloud Spanner) ✅ なぜFastAPIではなくConnect RPCか? 内部サービス間の高速通信。スキーマファーストで多言語環境に対応 🔧 Connect RPC 実装 私が開発したConnecpyを使用。現在Connecpyはconnect-python (connect-rpc orgのオフィシャル実装)に統合済み 📌 補足 Connecpyは社内のPython用マイクロサービステンプレートでも採用されている。 PydanticRPC内部でもConnecpy改めconnect-pythonを使用している。
  20. モノタロウ社内の実例(続き) 例② 基幹システムの顧客ドメイン Webブラウザ → フロントエンド (FastAPI with UI) →

    バックエンド (Connect RPC/gRPC) → DB(MySQL) ✅ なぜUI層はFastAPIか? 社内ツールなど、Web UIを持つフロントエンドサービスにはテンプレー トエンジン等との連携が容易なFastAPIが適している ✅ なぜバックエンドはRPCか? 純粋なデータ処理を行う内部ロジックであり、パフォーマンスが求められ る 他ドメインにこのサービスを提供することもあり得る 例③ 基幹システムの受注ドメイン Webブラウザ → フロントエンド (Next.js) → バックエンド (Connect RPC/gRPC) → DB(MySQL) ✅ なぜRPCか? Next.js (TypeScript) とバックエンド (Python) の間で、Connectを使い型安全な通信を実現するため
  21. Connect RPCの実践的な活用例 実践的な活用パターン 🔄 FastAPIとの共存 同一サーバーでRESTとRPCを使い分け • 外部API → REST

    • 内部通信 → RPC 段階的な移行も可能 ⚡ 高速通信 マイクロサービス間の低レイテンシ通信 • Envoy Proxyとの連携 • Unix Domain Socket活用 • バイナリProtobufで高速化 🌐 フロントエンドとの型安全な連携 TypeScript (Connect RPC) ⇄ Python (PydanticRPC) プロキシ不要・ブラウザから直接呼び出し・エンドツーエンドで型安全
  22. まとめ 📍 マイクロサービスの課題 サービス間通信のパフォーマンスと信頼性が課題となる 🎯 型駆動開発 厳格な「契約」により、開発生産性と品質を大幅に向上 🐍 vs 📜

    FastAPIの生産性とgRPCのパフォーマンス、それぞれの強み 🚀 PydanticRPC FastAPIの優れた開発者体験をgRPC/Connect RPCの世界に持ち込む 🎭 ハイブリッドアプローチ コードファーストで開発を始め、必要に応じて.protoファイルをエクスポート スキーマファーストの多言語連携へとスケール可能
  23. gRPCとは? 🚀 Googleが開発した高性能RPCフレームワーク gRPC(gRPC Remote Procedure Calls)は、Googleが開発したオープンソースのRPCフレームワーク マイクロサービス間の高速・効率的な通信を実現 📋 Protocol

    Buffers .protoファイルでスキーマ定義 コンパクトなバイナリ形式 多言語対応の自動コード生成 ⚡ 高速通信 HTTP/2ベースの効率的な通信 双方向ストリーミング対応 JSONに比べて軽量・高速 🌐 多言語サポート 主要対応言語: Go、Java、Python、C++、C#、Node.js、Ruby、PHP等 同一の.protoファイルから複数言語のクライアント・サーバーコードを自動生成
  24. Connect RPCとは? 🌐 gRPCの課題を解決する次世代プロトコル Connect RPCは、gRPCの強力さを保ちながら、 より使いやすく、ブラウザフレンドリーなRPCプロトコル 🌍 ブラウザ対応 ブラウザから直接呼び出し可能

    gRPC-Webが不要 HTTP/1.1とHTTP/2の両方に対応 🔧 開発者体験 curlやPostmanでテスト可能 標準的なHTTPツールが使える デバッグが簡単 📝 柔軟なデータ形式 JSONとProtobuf両方をサポート 開発時はJSON、本番時はProtobuf 用途に応じた使い分けが可能 🔄 互換性 gRPCとの互換性を保持 既存のHTTPインフラと共存 段階的な移行が可能