GitHubAPIでREST APIとGraphQLの比較
はじめに
GraphQLってなに?という状態でしたので調べました。
GitHubAPIを例にREST APIとGraphQLの比較をしました。
なんとなくイメージが掴むのが目的です。
REST APIとは
REST APIは、リソースごとにエンドポイントを定義し、HTTPメソッド(GET, POST, DELETE, PUT など)を使って操作を行います。各リソース(例: users
、repos
)にアクセスするためのURLがあり、リソースに対する操作がURLとHTTPメソッドで決定される。
例: GitHubのREST APIでユーザー情報を取得する場合
- エンドポイント:
/users/:username
- HTTPメソッド:
GET
- レスポンス: ユーザー情報のJSON
GET https://api.github.com/users/kabikira
レスポンス
{
"login": "kabikira",
"id": 96964536,
"node_id": "U_kgDOBcePuA",
"avatar_url": "https://avatars.githubusercontent.com/u/96964536?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/kabikira",
"html_url": "https://github.com/kabikira",
"followers_url": "https://api.github.com/users/kabikira/followers",
"following_url": "https://api.github.com/users/kabikira/following{/other_user}",
"gists_url": "https://api.github.com/users/kabikira/gists{/gist_id}",
"starred_url": "https://api.github.com/users/kabikira/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/kabikira/subscriptions",
"organizations_url": "https://api.github.com/users/kabikira/orgs",
"repos_url": "https://api.github.com/users/kabikira/repos",
"events_url": "https://api.github.com/users/kabikira/events{/privacy}",
"received_events_url": "https://api.github.com/users/kabikira/received_events",
"type": "User",
"site_admin": false,
"name": "Imael",
"company": null,
"blog": "",
"location": "Japan",
"email": null,
"hireable": null,
"bio": "Webエンジニアです。iOSエンジニアに転職したい!",
"twitter_username": null,
"public_repos": 100,
"public_gists": 0,
"followers": 6,
"following": 5,
"created_at": "2022-01-02T02:23:33Z",
"updated_at": "2024-09-02T15:32:49Z"
}
REST APIの問題点:
- エンドポイントが多くなる: 各リソースごとにエンドポイントを作成する必要があり、アプリケーションが大きくなるほどエンドポイントが増加する。
- 不要なデータを含む: エンドポイントに対応する固定のレスポンス形式でデータが返ってくるため、クライアントが必要としないデータも含まれることが多い。
- 複数リソースの取得が複雑: 例えば、ユーザー情報とそのリポジトリ情報を取得するには、それぞれ異なるエンドポイントを複数回呼び出す必要がある。
GraphQLとは
Facebook社 が開発したWebAPIのクエリ言語
2012年にモバイルアプリケーション向けに開発がスタートして2015年にオープンソース化
GraphQLは、単一のエンドポイントからクエリを使用して必要なデータを取得する方法です。クライアントが必要なデータをクエリで指定し、バックエンドはそのリクエストに応じて、指定されたデータだけを返します。
GraphQLのクエリとはAPIに対するクエリです。
例: GitHubのGraphQL APIでユーザー情報を取得する場合
- エンドポイント:
/graphql
- クエリで必要な情報を指定:
query { user(login: "kabikira") { login name repositories(first: 10) { nodes { name description } } } }
- query: これはクエリ操作の開始を示します。
- user(login: "kabikira"): "kabikira"というログイン名を持つユーザーの情報を取得します。
- login と name: ユーザーのログイン名と実名を取得します。
- repositories(first: 10): このユーザーの最初の10個のリポジトリを取得します。
- nodes: リポジトリのリストを表します。
- name と description: 各リポジトリの名前と説明を取得します。
このクエリを実行すると、指定したユーザーのログイン名、実名、そして最初の10個のリポジトリの名前と説明が返されます。GraphQLの特徴として、必要な情報だけを一度のリクエストで取得できることがわかります。
レスポンス
{
"data": {
"user": {
"login": "kabikira",
"name": "Imael",
"repositories": {
"nodes": [
{
"name": "TimerApp",
"description": null
},
{
"name": "PandaTimer",
"description": null
},
{
"name": "CoreDataTimer",
"description": null
},
{
"name": "KaossilatorMad",
"description": null
},
{
"name": "AudioRecorderEffect",
"description": null
},
{
"name": "RandomEffectsVoic-Recorder",
"description": null
},
{
"name": "RandomRecorderTest",
"description": null
},
{
"name": "webView",
"description": null
},
{
"name": "Coin-Dice",
"description": null
},
{
"name": "FleaMarketSearch",
"description": "複数のフリマサイトを一括で検索するアプリ"
}
]
}
}
}
}
こちらで実行できます。
特徴:
- 必要なデータだけを取得: クライアントがクエリを作成するため、不要なデータがレスポンスに含まれない。これにより、通信コストや処理の無駄が減る。
- 柔軟なデータ取得: 一度のクエリで複数のリソースを指定できるため、REST APIのように複数回リクエストする必要がない。たとえば、上記のクエリでユーザー情報とそのリポジトリ情報を一度に取得できる。
-
型指定が可能:
もし「名前は文字列、年齢は整数」と決めてあるのに、「名前に数字を入れる」といった間違いをしようとすると、エラーが発生してそのミスを防いでくれる。
やり取りするデータの型がはっきりしているので、間違いが少なくて安心。
GraphQLの問題点:
-
学習コスト:
- スキーマベースでクエリを組み立てる必要があるため、GraphQLのスキーマやクエリ構造に対する理解が必要。
-
セキュリティリスク:
- クライアントが自由にクエリを組み立てられるため、大規模なクエリを意図せず実行してサーバーの負荷が高くなる可能性がある。また、過剰に詳細な情報を要求されるリスクもある。
-
クエリの最適化:
- クエリの作り方次第でパフォーマンスが左右される。特に複雑なクエリでは、サーバーサイドの処理が複雑になりやすい。
REST APIとGraphQLの主な対比
項目 | REST API | GraphQL |
---|---|---|
エンドポイント | リソースごとにエンドポイントを定義 | 単一のエンドポイント |
データ取得方法 | エンドポイントに対してHTTPメソッドを使って操作 | クライアントがクエリを組み立てて必要なデータだけを取得 |
必要なデータ量 | 固定されたレスポンスで不要なデータも含まれることが多い | 必要なデータだけを取得 |
複数リソース取得 | 複数エンドポイントへのリクエストが必要 | 一度のクエリで複数リソースを取得 |
型安全性 | 型に依存せず、APIドキュメントからの解釈が必要 | スキーマによって型が保証される |
パフォーマンス | 無駄なデータが含まれることで通信量が増える可能性がある | 不要なデータがないため通信量が減少し、パフォーマンス向上 |
学習コスト | 比較的低い(一般的に普及している) | 高い(スキーマ、クエリ構造の理解が必要) |
おわりに
GraphQLはNetflix、メルカリ、楽天、Airbnb、Twitter、GitHub,AmazonWEBサービス、スタディサプリ等の大きなサービスで使われているみたいです。
参考
Discussion