要点(TL;DR)
パブリックAPIやシンプルなCRUD操作にはRESTを使用します。クライアントが柔軟なデータ取得を必要とし、オーバーフェッチを減らしたい場合はGraphQLを使用します。高性能なマイクロサービス間通信にはgRPCを使用します。Modern PetstoreAPIはこれら3つのプロトコルすべてを実装しており、各ユースケースに最適なツールを選択できます。
はじめに
あなたはAPIを構築しています。REST、GraphQL、それともgRPCを使うべきでしょうか?それぞれのプロトコルには、自分のものが最高だと主張する熱心な支持者がいます。しかし実のところ、これらはすべて異なる得意分野を持っています。
RESTは普遍的でシンプルです。GraphQLはクライアントにデータ取得の制御を与えます。gRPCは高速で、内部サービスにとって効率的です。最適な選択は、どのプロトコルが「優れているか」ではなく、あなたのユースケースによって決まります。
ほとんどのAPIは1つのプロトコルを選び、それを使い続けます。Modern PetstoreAPIは異なるアプローチを取っています。REST、GraphQL、gRPCを実装し、同じペットストアAPIがこれら3つのプロトコルすべてでどのように機能するかを示しています。
このガイドでは、各プロトコルの長所と短所を学び、Modern PetstoreAPIの実際の例を見て、あなたのニーズに合ったプロトコルを選択する方法を発見するでしょう。
REST: 普遍的な標準
REST (Representational State Transfer) は最も一般的なAPIプロトコルです。
RESTの仕組み
リソースはHTTPメソッドとURLを介してアクセスされます。
GET /pets - List pets
POST /pets - Create pet
GET /pets/{id} - Get pet
PUT /pets/{id} - Update pet
DELETE /pets/{id} - Delete pet
リクエストの例:
GET https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24
レスポンスの例:
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"species": "CAT",
"status": "AVAILABLE",
"price": 299.99
}
RESTの長所
1. 普遍的な互換性
すべてのプログラミング言語にはHTTPライブラリがあります。ブラウザ、curl、Postmanなど、すべてRESTで動作します。
2. 理解しやすいシンプルさ
URLはリソースを表し、HTTPメソッドはアクションを表します。その思考モデルは非常に分かりやすいです。
3. キャッシュ可能
HTTPキャッシングはすぐに機能します。GETリクエストはブラウザ、CDN、プロキシによってキャッシュできます。
4. ステートレス
各リクエストは独立しています。サーバー上にセッション状態はありません。
5. 優れたツール群
OpenAPI仕様、Swagger UI、APIテストツールなど、RESTは最高のエコシステムを持っています。
RESTの短所
1. オーバーフェッチ
必要なフィールドが1つだけであっても、すべてのフィールドを取得してしまいます。
// あなたが必要なのは名前だけですが、すべてを取得します
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"species": "CAT",
"status": "AVAILABLE",
"price": 299.99,
"description": "...",
"images": [...],
"vaccinations": [...]
}
2. アンダーフェッチ(N+1問題)
ペットとその注文を取得するには、複数のリクエストが必要です。
GET /pets/123 # ペットを取得
GET /pets/123/orders # 注文を取得
GET /orders/456/items # 注文品目を取得
3. バージョニングの複雑さ
破壊的変更には新しいAPIバージョン(/v1、/v2)が必要です。
4. リアルタイム更新の欠如
RESTはリクエスト・レスポンス型です。リアルタイムデータのためには、ポーリングまたはWebSocketが必要です。
RESTを使用すべき時
- パブリックAPI(最大限の互換性)
- シンプルなCRUD操作
- キャッシングが重要な場合
- 幅広いツールサポートが必要な場合
- 予測可能なデータニーズを持つモバイルアプリ
GraphQL: 柔軟なデータ取得
GraphQLは、クライアントが必要なデータを正確に指定できるようにします。
GraphQLの仕組み
クエリ言語を持つ単一のエンドポイント。
query {
pet(id: "019b4132-70aa-764f-b315-e2803d882a24") {
name
species
orders {
id
total
items {
product
quantity
}
}
}
}
レスポンス:
{
"data": {
"pet": {
"name": "Fluffy",
"species": "CAT",
"orders": [
{
"id": "order-123",
"total": 49.99,
"items": [
{"product": "Cat food", "quantity": 2}
]
}
]
}
}
}
GraphQLの長所
1. オーバーフェッチなし
クライアントは必要なフィールドのみをリクエストします。
query {
pet(id: "019b4132-70aa-764f-b315-e2803d882a24") {
name # 名前だけを取得
}
}
2. アンダーフェッチなし
関連データを1つのリクエストで取得します。
query {
pet(id: "019b4132-70aa-764f-b315-e2803d882a24") {
name
orders {
items {
product
}
}
}
}
N+1問題なし。
3. 強力な型付け
GraphQLスキーマは強力な型付けがされています。クライアントは何が利用可能かを正確に知っています。
4. イントロスペクション
クライアントはスキーマをクエリして、利用可能な操作を調べることができます。
query {
__schema {
types {
name
fields {
name
type
}
}
}
}
5. 単一のエンドポイント
すべての操作は1つのURL(/graphql)を介して行われます。
GraphQLの短所
1. 複雑性
GraphQLはRESTよりも学習が難しいです。クエリ、ミューテーション、サブスクリプション、リゾルバーなど、理解すべきことが多くあります。
2. キャッシングの難しさ
HTTPキャッシングはうまく機能しません。カスタムのキャッシング戦略が必要です。
3. オーバークエリのリスク
クライアントは負荷の高いクエリを記述する可能性があります。
query {
pets {
orders {
items {
product {
reviews {
author {
pets {
# 無限の深さ!
}
}
}
}
}
}
}
}
クエリの深さ制限と複雑性分析が必要です。
4. ファイルアップロードの扱いにくさ
GraphQLはファイルアップロードのために設計されていません。回避策が必要です。
5. 監視の難しさ
すべてのリクエストが/graphqlに送られるため、URLによる監視はできません。
GraphQLを使用すべき時
- モバイルアプリ(帯域幅の削減)
- 複雑なデータ要件
- クライアントが柔軟性を必要とする場合
- クライアントが既知の内部API
- バージョニングを避けたい場合
gRPC: 高性能RPC
gRPCは効率的なバイナリ通信のためにProtocol Buffersを使用します。
gRPCの仕組み
.protoファイルでサービスを定義します。
service PetService {
rpc GetPet(GetPetRequest) returns (Pet);
rpc ListPets(ListPetsRequest) returns (ListPetsResponse);
rpc CreatePet(CreatePetRequest) returns (Pet);
}
message Pet {
string id = 1;
string name = 2;
string species = 3;
PetStatus status = 4;
}
クライアントコード(生成されたもの):
client := pb.NewPetServiceClient(conn)
pet, err := client.GetPet(ctx, &pb.GetPetRequest{
Id: "019b4132-70aa-764f-b315-e2803d882a24",
})
gRPCの長所
1. パフォーマンス
Protocol BuffersはJSONよりも小さく、高速です。
- ペイロードが3~10倍小さい
- シリアル化が20~100倍速い
2. ストリーミング
サーバーサイドストリーミング、クライアントサイドストリーミング、双方向ストリーミングを組み込みでサポートします。
rpc WatchPets(WatchPetsRequest) returns (stream Pet);
3. 強力な型付け
Protocol Buffersはコンパイル時に型を強制します。
4. コード生成
.protoファイルから10以上の言語でクライアントおよびサーバーコードを生成します。
5. HTTP/2
多重化、ヘッダー圧縮、サーバープッシュ。
gRPCの短所
1. ブラウザに優しくない
ブラウザはHTTP/2の双方向ストリーミングをサポートしていません。grpc-web(回避策)が必要です。
2. 人間が読みにくい
Protocol Buffersはバイナリです。gRPCエンドポイントをcurlで叩いてレスポンスを読むことはできません。
3. デバッグが難しい
バイナリプロトコルはJSONよりも検査が困難です。
4. ツールが少ない
RESTと比較してツールが少ないです。Swagger UIに相当するものはありません。
5. 急な学習曲線
Protocol Buffers、コード生成、およびgRPCの概念を学ぶには時間がかかります。
gRPCを使用すべき時
- マイクロサービス間通信
- 高性能要件
- リアルタイムストリーミング
- 内部API(公開されないもの)
- 多言語環境(複数の言語)
サイドバイサイド比較
| 機能 | REST | GraphQL | gRPC |
|---|---|---|---|
| プロトコル | HTTP/1.1 または HTTP/2 | HTTP/1.1 または HTTP/2 | HTTP/2 のみ |
| データ形式 | JSON(通常) | JSON | Protocol Buffers(バイナリ) |
| エンドポイント | 複数(/pets, /orders) |
単一(/graphql) |
サービスメソッド |
| オーバーフェッチ | 一般的 | 稀 | 該当なし(メッセージを定義) |
| アンダーフェッチ | 一般的(N+1) | 稀 | 該当なし |
| キャッシング | 優れている(HTTP) | 劣る | 劣る |
| ブラウザサポート | 優れている | 優れている | 劣る(grpc-webが必要) |
| ツール群 | 優れている | 良い | 普通 |
| 学習曲線 | 簡単 | 中程度 | 難しい |
| パフォーマンス | 良い | 良い | 優れている |
| ストリーミング | なし(WebSocketが必要) | あり(サブスクリプション) | あり(ネイティブ) |
| バージョニング | URLまたはヘッダー | スキーマの進化 | Protoの進化 |
| 最適用途 | 公開API、CRUD | 柔軟なクライアント | マイクロサービス |
Modern PetstoreAPIが3つのプロトコルすべてを実装する方法
Modern PetstoreAPIはユニークです。同じペットストアAPIをREST、GraphQL、gRPCで実装しています。
同じデータ、3つのプロトコル
IDによるペットの取得:
REST:
GET https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24
GraphQL:
query {
pet(id: "019b4132-70aa-764f-b315-e2803d882a24") {
id
name
species
}
}
gRPC:
pet, err := client.GetPet(ctx, &pb.GetPetRequest{
Id: "019b4132-70aa-764f-b315-e2803d882a24",
})
これら3つすべてが同じペットデータを返します。
なぜ3つすべてを実装するのか?
1. 比較による学習
異なるプロトコルで同じ操作がどのように機能するかを確認する。
2. 適切なツールの選択
パブリックエンドポイントにはREST、モバイルアプリにはGraphQL、内部サービスにはgRPCを使用する。
3. 移行パス
RESTから始め、後でGraphQLやgRPCを追加する際にすべてを書き直す必要がない。
4. リファレンス実装
Modern PetstoreAPIは、3つのプロトコルすべてについて本番環境に対応したパターンを示しています。
詳細な例については、プロトコル比較ガイドを確認してください。
ApidogによるマルチプロトコルAPIのテスト
Apidogは、REST、GraphQL、gRPCを1つのツールでサポートしています。
RESTのテスト
OpenAPI仕様をインポートし、自動テストを実行します。
pm.test("Status is 200", () => {
pm.response.to.have.status(200);
});
pm.test("Pet has required fields", () => {
const pet = pm.response.json();
pm.expect(pet).to.have.property('id');
pm.expect(pet).to.have.property('name');
});
GraphQLのテスト
GraphQLクエリを記述し、レスポンスを検証します。
query GetPet($id: ID!) {
pet(id: $id) {
id
name
species
}
}
ApidogはGraphQLスキーマに対して検証を行います。
gRPCのテスト
.protoファイルをインポートし、gRPCサービスをテストします。
service: PetService
method: GetPet
request: { "id": "019b4132-70aa-764f-b315-e2803d882a24" }
ApidogはProtocol Buffer定義からリクエストを生成します。
クロスプロトコルテスト
3つのプロトコルすべてが一貫したデータを返すことをテストします。
- RESTエンドポイントを呼び出す
- GraphQLクエリを呼び出す
- gRPCメソッドを呼び出す
- レスポンスを比較する
Apidogは、マルチプロトコルAPIの一貫性を維持するのに役立ちます。
適切なプロトコルの選択
この決定ツリーを使用してください。
これはパブリックAPIですか?→ はい: RESTを使用(最大限の互換性) → いいえ: 次へ
リアルタイムストリーミングが必要ですか?→ はい: gRPCまたはWebSocketを使用 → いいえ: 次へ
クライアントは柔軟なデータ取得を必要としますか?→ はい: GraphQLを使用 → いいえ: 次へ
パフォーマンスは重要ですか(マイクロサービス)?→ はい: gRPCを使用 → いいえ: RESTを使用(最もシンプルな選択肢)
実際の事例
- Stripe: REST(パブリックAPI、シンプル、キャッシュ可能)
- GitHub: REST + GraphQL(パブリックにはREST、複雑なクエリにはGraphQL)
- Google Cloud: gRPC + REST(パフォーマンスにはgRPC、互換性にはREST)
- Netflix: GraphQL(モバイルアプリは柔軟なデータを必要とする)
- Uber: gRPC(マイクロサービス間通信)
複数のプロトコルを使用できますか?
はい!Modern PetstoreAPIがその方法を示しています。一般的なパターンは次のとおりです。
- 公開APIにはREST
- モバイルアプリにはGraphQL
- 内部マイクロサービスにはgRPC
各プロトコルは、異なるニーズを持つ異なるクライアントに対応します。
結論
REST、GraphQL、gRPCは競合するものではなく、それぞれ異なる仕事のためのツールです。RESTは普遍的でシンプル、GraphQLはクライアントに制御を与え、gRPCは高速で効率的です。
Modern PetstoreAPIはこれら3つすべてを実装しており、同じAPIがプロトコルを越えてどのように機能するかを示しています。本番環境に対応した例を見るために、RESTドキュメント、GraphQLスキーマ、gRPCプロトファイルを探索できます。
Apidogを使用して、3つのプロトコルすべてをテストし、実装を比較し、マルチプロトコルAPI全体で一貫性を確保してください。
最良のプロトコルは、あなたの特定の課題を解決するものです。Modern PetstoreAPIは、賢明な選択をするための知識を提供します。
よくある質問(FAQ)
RESTとGraphQLを一緒に使えますか?
はい。多くのAPIが両方を提供しています。シンプルな操作にはRESTを、複雑なクエリにはGraphQLを使用します。GitHubがこの方法を採用しています。
gRPCはRESTに取って代わりますか?
いいえ。gRPCは内部マイクロサービス向けです。RESTは、より良い互換性とツール群があるため、パブリックAPIの標準であり続けています。
どのプロトコルが最も速いですか?
gRPCはProtocol BuffersとHTTP/2のおかげで最も高速です。しかし、ほとんどのAPIではその違いは重要ではありません。ネットワークの遅延が支配的です。
RESTからGraphQLに移行すべきですか?
オーバーフェッチ/アンダーフェッチの問題がある場合にのみ移行してください。GraphQLが流行しているからといって安易に移行すべきではありません。
ブラウザはgRPCを使えますか?
直接は使えません。複雑さが増すgrpc-webが必要です。ブラウザクライアントにはRESTまたはGraphQLを使用してください。
Modern PetstoreAPIは3つのプロトコルすべてをどのように同期させていますか?
共有ビジネスロジック層を使用しています。REST、GraphQL、gRPCは、同じコアAPIの上に構築された薄いプロトコルアダプターです。
スタートアップはどのプロトコルを使用すべきですか?
まずはRESTから始めましょう。シンプルでよく理解されており、優れたツールがあります。必要に応じて後からGraphQLやgRPCを追加してください。
Apidogは3つのプロトコルすべてをサポートしていますか?
はい。ApidogはREST(OpenAPI)、GraphQL、gRPCを1つのツールでサポートしており、Modern PetstoreAPIのようなマルチプロトコルAPIのテストを容易にします。
