【図解】REST・GraphQL・gRPC・Webhookの違いとは?APIの呼び出し方を初心者向けに解説

以前、REST APIの基本とAPIエンドポイントの読み方を記事にしました。ところが API の資料を読んでいると、GraphQL や gRPC、Webhook のように、REST とは呼び出し方の違う API もよく出てきます。この記事では、4つの呼び出し方の違いを、GitHub・Microsoft・gRPC の公式ドキュメントで確かめながら図にしました。

この記事でわかること
  1. REST・GraphQL・gRPC・Webhook のそれぞれの呼び出し方
  2. URL の数、呼ぶ向き、データの形がどう違うか
  3. 守る側から見たときに、どこを見ればよいかの違い

API の呼び出し方は1つではない

API は、プログラムどうしがやり取りするための窓口です。窓口の作り方にはいくつかの型があり、よく見かけるのが REST・GraphQL・gRPC・Webhook の4つです。どれも HTTP の上で動くことが多いのですが、URL の数や、誰が誰を呼ぶかが違います。

REST/users/groups/meクライアントAPI サーバリソースごとに URL があるGraphQL/graphql{ user { name } }クライアントAPI サーバ1つの URL に、欲しい形を書いて送るgRPCSayHello()HTTP/2Protocol BuffersクライアントAPI サーバ相手の関数を呼ぶように呼び出すWebhookイベントが起きたら通知あらかじめ登録した URL へサービス自分のアプリ向こうから届く(呼ぶ向きが逆)
図1 4つの呼び出し方の違い
型ひとことで言うと例
RESTリソースごとに URL があり、HTTP メソッドで操作を表すMicrosoft Graph、Azure Resource Manager
GraphQL1つの 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(3回に分けて取る例)クライアントAPI サーバGET /users/{id}GET /users/{id}/followersGET /users/{id}/repos毎回、決まった形のデータが返るGraphQL(1回で取る例)クライアントAPI サーバPOST /graphqluser { name followers { name }}頼んだ項目だけが返るクエリの書き方は説明用の例
図2 REST と GraphQL の取り方の違い

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 の仕様書の役目をします。

HTTP のステータスだけで判断しない

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 を呼ぶだけで、裏ではサーバへのリクエストが送られます。

コードを生成コードを生成.protoサービスとメッセージの定義クライアントスタブ(呼び出し口)サーバサービスの実装SayHello(HelloRequest)HelloReplyHTTP/2 の上で、Protocol Buffers(バイナリ)のメッセージをやり取りするリクエストは POST、パスは /サービス名/メソッド名
図3 gRPC は .proto から作ったコードで、関数を呼ぶように通信する

通信には HTTP/2 を使います。gRPC の仕様では、リクエストのメソッドは POST、パスは /サービス名/メソッド名、Content-Type は application/grpc で始まる値と決められています。中身は Protocol Buffers のバイナリなので、REST の JSON のようにそのまま目で読むことはできません。

呼び出しの種類やり取り
Unaryリクエスト1つに、レスポンス1つ。ふつうの関数呼び出しと同じ
サーバストリーミングリクエスト1つに対して、サーバから続けてメッセージが届く
クライアントストリーミングクライアントが続けてメッセージを送る
双方向ストリーミング両方が続けてメッセージを送り合う

Webhook:向こうから呼んでくれる

ここまでの3つは、クライアントがサーバを呼ぶ型でした。Webhook は向きが逆で、サービスの側でイベントが起きたときに、あらかじめ登録しておいた URL へサービスから HTTP リクエストが届きます。GitHub の資料では、API を何度も呼んで新しいデータがないか確かめる「ポーリング」と比べて、起きたときにデータを受け取るしくみとして説明しています。

ポーリング(自分から何度も聞く)自分のアプリサービス新しい変更はある?変更なし新しい変更はある?変更なし新しい変更はある?変更あり変化がなくても問い合わせが続くWebhook(向こうから届く)自分のアプリサービス受け口の URL を登録(最初に1回)イベント発生通知(HTTP リクエスト)変化があったときだけ届く
図4 ポーリングと Webhook の違い

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つを並べて比べる

項目RESTGraphQLgRPCWebhook
呼ぶ向きクライアント→サーバクライアント→サーバクライアント→サーバサービス→受け手
URLリソースごとに多数1つにまとまる(/graphql が慣例)/サービス名/メソッド名受け手が用意する
主な HTTPGET・POST・PUT・PATCH・DELETEPOST が基本HTTP/2 の POSTサービスが決める
データJSON が多いJSON(クエリを入れて送る)Protocol Buffers(バイナリ)JSON が多い
仕様の書き方OpenAPIスキーマ.proto送り手の資料

守る側から見たときの違い

型が違うと、入口でのチェックやログの見方も変わります。どれが安全という話ではなく、それぞれ見るところが違う、という整理です。

型見るところ
RESTURL とメソッドの組み合わせで操作がわかるので、入口のルールやログを URL 単位で考えやすい
GraphQLURL が1つにまとまるので、URL だけでは何をしているかわからない。OWASP は、クエリの深さや量に上限を設けることと、本番や公開の環境でイントロスペクションを無効にすることを勧めている。GET で mutation を受け付けないことも仕様の草案で決められている
gRPCHTTP/2 で通る必要があるので、途中のプロキシやロードバランサが HTTP/2 と gRPC を通せるか確かめる。中身はバイナリなので、ログで中身を見るには .proto の定義が要る
Webhook受け口の URL が送り手から届く場所に公開される。署名や clientState で送り主を確かめ、届いた値は信用しすぎずに扱う
補足:JSON-RPC

4つのほかに、JSON-RPC という型もあります。呼び出したいメソッド名と引数を JSON に入れて送る、シンプルな決まりです。AI エージェントとツールをつなぐ MCP(Model Context Protocol)でも、クライアントとサーバの間のメッセージは JSON-RPC 2.0 に従うと決められています。

まとめ

項目ポイント
RESTリソースごとに URL があり、HTTP メソッドで操作を表す。Microsoft Graph は名前に反して REST
GraphQL1つの URL に欲しい形のクエリを送る。HTTP 200 でも errors を確かめる
gRPC.proto で定義し、HTTP/2 と Protocol Buffers で関数のように呼ぶ
Webhook呼ぶ向きが逆。受け口を自分で用意し、送り主を確かめる
守る側URL で見分けられる型と、中身を見ないとわからない型がある

参考にした資料

この記事は、次の仕様と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。

あとがき

4つを1枚の表に並べてみると、同じ「API」でも、URL の数や呼ぶ向きがかなり違うことがよくわかります。Microsoft Graph が名前に Graph と付いていても REST API だという点も、図を描きながら公式ドキュメントで確かめたところです。資料で見慣れない API が出てきたら、まず「誰が誰を呼ぶか」と「URL がいくつあるか」を見ると、どの型かの見当がつきます。

コメント