以前、REST APIの基本とAPIエンドポイントの読み方を記事にしました。ところが API の資料を読んでいると、GraphQL や gRPC、Webhook のように、REST とは呼び出し方の違う API もよく出てきます。この記事では、4つの呼び出し方の違いを、GitHub・Microsoft・gRPC の公式ドキュメントで確かめながら図にしました。
- REST・GraphQL・gRPC・Webhook のそれぞれの呼び出し方
- URL の数、呼ぶ向き、データの形がどう違うか
- 守る側から見たときに、どこを見ればよいかの違い
API の呼び出し方は1つではない
API は、プログラムどうしがやり取りするための窓口です。窓口の作り方にはいくつかの型があり、よく見かけるのが REST・GraphQL・gRPC・Webhook の4つです。どれも HTTP の上で動くことが多いのですが、URL の数や、誰が誰を呼ぶかが違います。
| 型 | ひとことで言うと | 例 |
|---|---|---|
| REST | リソースごとに URL があり、HTTP メソッドで操作を表す | Microsoft Graph、Azure Resource Manager |
| GraphQL | 1つの URL に、欲しいデータの形を書いたクエリを送る | GitHub の GraphQL API |
| gRPC | 相手のメソッドを関数のように呼ぶ。HTTP/2 とバイナリでやり取りする | サービスどうしの内部通信 |
| Webhook | イベントが起きたときに、サービスの側から通知が届く | GitHub の Webhook、Microsoft Graph の変更通知 |
REST:リソースごとに URL がある
REST は、ユーザーやグループのような「リソース」ごとに URL を用意し、GET(取得)や POST(作成)などの HTTP メソッドで操作を表す型です。しくみは REST APIの記事で説明しています。
例:Microsoft Graph のユーザー一覧(公式ドキュメントのリクエスト例)
GET https://graph.microsoft.com/v1.0/users
Microsoft Graph は名前に「Graph」と付いていますが、GraphQL ではありません。Microsoft の資料では、Microsoft Graph を RESTful な Web API と説明しています。
GraphQL:1つの URL に「欲しい形」を送る
GraphQL は、クライアントが欲しいデータの形を「クエリ」として書いて送る型です。GitHub の資料では、REST API にはたくさんのエンドポイントがある一方で、GraphQL API は操作に関係なくエンドポイントが変わらない、と説明しています。GitHub の GraphQL API のエンドポイントは https://api.github.com/graphql の1つです。
REST では、ほしい情報が複数のリソースにまたがると、URL ごとに何度もリクエストを送ることになり、それぞれ決まった形のデータが返ります。GraphQL では、必要な項目をクエリにまとめて1回で送り、頼んだ項目だけを受け取れます。GitHub は、REST の複数回のリクエストにあたる内容を1回の GraphQL のリクエストで行えることを、GraphQL の利点として挙げています。
例:GitHub の GraphQL API(公式ドキュメントの curl の例を HTTP リクエストの形にしたもの)
POST https://api.github.com/graphql
Authorization: bearer TOKEN
{"query": "query { viewer { login }}"}
GitHub の GraphQL API では、データを読む query も、書き換える mutation も、JSON の本文を付けた POST で送ります。GitHub の資料では、query は REST の GET に、mutation は POST・PATCH・DELETE にあたると説明しています。
| 操作の種類 | 意味(GraphQL の仕様) |
|---|---|
| query | 読み取りだけの取得 |
| mutation | 書き込みをして、その結果を取得する |
| subscription | 長く続くリクエストで、イベントが起きるたびにデータを受け取る |
GraphQL のサービスは、扱えるデータの型を「スキーマ」として持っていて、そのスキーマ自体を GraphQL で問い合わせられます。これをイントロスペクションといいます。REST の OpenAPI のように、スキーマが API の仕様書の役目をします。
GraphQL では、HTTP のステータスが 200 でも、レスポンスの中に errors が入っていることがあります。GraphQL を HTTP で使うときの決まりを書いた仕様の草案でも、従来の application/json の応答では、実行時のエラーがあっても 200 を返すとしています。結果を確かめるときは、本文の errors も見ます。
gRPC:相手の関数を呼ぶように呼び出す
gRPC は、別のマシンで動いているサーバのメソッドを、手元の関数のように呼び出す型です。使えるメソッドと、やり取りするメッセージの形を、.proto というファイルに書いて決めます。gRPC は既定で Protocol Buffers を使い、これがサービスを定義する言葉(IDL)にも、メッセージの形式にもなります。
例:サービスの定義(gRPC の公式ドキュメントの例から抜粋)
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
この定義から、クライアント用の「スタブ」とサーバ用のコードを作ります。クライアントはスタブの SayHello を呼ぶだけで、裏ではサーバへのリクエストが送られます。
通信には HTTP/2 を使います。gRPC の仕様では、リクエストのメソッドは POST、パスは /サービス名/メソッド名、Content-Type は application/grpc で始まる値と決められています。中身は Protocol Buffers のバイナリなので、REST の JSON のようにそのまま目で読むことはできません。
| 呼び出しの種類 | やり取り |
|---|---|
| Unary | リクエスト1つに、レスポンス1つ。ふつうの関数呼び出しと同じ |
| サーバストリーミング | リクエスト1つに対して、サーバから続けてメッセージが届く |
| クライアントストリーミング | クライアントが続けてメッセージを送る |
| 双方向ストリーミング | 両方が続けてメッセージを送り合う |
Webhook:向こうから呼んでくれる
ここまでの3つは、クライアントがサーバを呼ぶ型でした。Webhook は向きが逆で、サービスの側でイベントが起きたときに、あらかじめ登録しておいた URL へサービスから HTTP リクエストが届きます。GitHub の資料では、API を何度も呼んで新しいデータがないか確かめる「ポーリング」と比べて、起きたときにデータを受け取るしくみとして説明しています。
Webhook を受ける側は、通知を受け取るためのエンドポイントを自分で用意します。つまり、Webhook では「API を使う側」が受け口の URL を持つことになります。
Microsoft Graph にも、Webhook で変更を知らせる「変更通知」があります。購読(サブスクリプション)を作るときに受け口の URL(notificationUrl)を渡すと、Microsoft Graph は確認用のトークンを付けたリクエストをその URL に送り、正しく応答できたときだけ購読を作ります。
例:Microsoft Graph が受け口の URL を確かめるリクエスト(公式ドキュメントの例)
POST https://{notificationUrl}?validationToken={opaqueTokenCreatedByMicrosoftGraph}
受け口は誰からでもリクエストを受け付けられる場所にあるので、届いた通知が本物かを確かめる必要があります。GitHub は秘密の値から作った署名を X-Hub-Signature-256 ヘッダに入れて送り、Microsoft Graph は購読のときに決めた clientState の値を通知に入れて送ります。署名に使う HMAC のしくみは暗号の基礎の記事で説明しています。
4つを並べて比べる
| 項目 | REST | GraphQL | gRPC | Webhook |
|---|---|---|---|---|
| 呼ぶ向き | クライアント→サーバ | クライアント→サーバ | クライアント→サーバ | サービス→受け手 |
| URL | リソースごとに多数 | 1つにまとまる(/graphql が慣例) | /サービス名/ | 受け手が用意する |
| 主な HTTP | GET・POST・PUT・PATCH・DELETE | POST が基本 | HTTP/2 の POST | サービスが決める |
| データ | JSON が多い | JSON(クエリを入れて送る) | Protocol Buffers(バイナリ) | JSON が多い |
| 仕様の書き方 | OpenAPI | スキーマ | .proto | 送り手の資料 |
守る側から見たときの違い
型が違うと、入口でのチェックやログの見方も変わります。どれが安全という話ではなく、それぞれ見るところが違う、という整理です。
| 型 | 見るところ |
|---|---|
| REST | URL とメソッドの組み合わせで操作がわかるので、入口のルールやログを URL 単位で考えやすい |
| GraphQL | URL が1つにまとまるので、URL だけでは何をしているかわからない。OWASP は、クエリの深さや量に上限を設けることと、本番や公開の環境でイントロスペクションを無効にすることを勧めている。GET で mutation を受け付けないことも仕様の草案で決められている |
| gRPC | HTTP/2 で通る必要があるので、途中のプロキシやロードバランサが HTTP/2 と gRPC を通せるか確かめる。中身はバイナリなので、ログで中身を見るには .proto の定義が要る |
| Webhook | 受け口の URL が送り手から届く場所に公開される。署名や clientState で送り主を確かめ、届いた値は信用しすぎずに扱う |
4つのほかに、JSON-RPC という型もあります。呼び出したいメソッド名と引数を JSON に入れて送る、シンプルな決まりです。AI エージェントとツールをつなぐ MCP(Model Context Protocol)でも、クライアントとサーバの間のメッセージは JSON-RPC 2.0 に従うと決められています。
まとめ
| 項目 | ポイント |
|---|---|
| REST | リソースごとに URL があり、HTTP メソッドで操作を表す。Microsoft Graph は名前に反して REST |
| GraphQL | 1つの URL に欲しい形のクエリを送る。HTTP 200 でも errors を確かめる |
| gRPC | .proto で定義し、HTTP/2 と Protocol Buffers で関数のように呼ぶ |
| Webhook | 呼ぶ向きが逆。受け口を自分で用意し、送り主を確かめる |
| 守る側 | URL で見分けられる型と、中身を見ないとわからない型がある |
参考にした資料
この記事は、次の仕様と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。
- GraphQL Specification (October 2021)(GraphQL Foundation):query・mutation・subscription の定義、型の問い合わせ
- GraphQL over HTTP(Working Draft)(GraphQL Foundation):URL の慣例、POST と GET、ステータスコード
- Introduction to gRPC・Core concepts, architecture and lifecycle(gRPC):スタブ、Protocol Buffers、.proto の例、4種類の呼び出し
- gRPC over HTTP2(grpc/grpc リポジトリ):POST、パス、Content-Type
- Model Context Protocol Specification: Overview(Model Context Protocol):メッセージが JSON-RPC 2.0 に従うこと
- GraphQL Cheat Sheet(OWASP):クエリの深さ・量の制限、イントロスペクションの無効化
- Use the Microsoft Graph API(Microsoft Learn):Microsoft Graph が RESTful な Web API であること
- List users(Microsoft Learn):ユーザー一覧のリクエスト例
- Receive change notifications through webhooks(Microsoft Learn):notificationUrl の確認、clientState
- Forming calls with GraphQL・Comparing GitHub’s REST API and GraphQL API(GitHub Docs):1つのエンドポイント、POST、query と mutation、REST との違い
- About webhooks・Validating webhook deliveries(GitHub Docs):ポーリングとの違い、X-Hub-Signature-256
あとがき
4つを1枚の表に並べてみると、同じ「API」でも、URL の数や呼ぶ向きがかなり違うことがよくわかります。Microsoft Graph が名前に Graph と付いていても REST API だという点も、図を描きながら公式ドキュメントで確かめたところです。資料で見慣れない API が出てきたら、まず「誰が誰を呼ぶか」と「URL がいくつあるか」を見ると、どの型かの見当がつきます。
コメント