🪬

GitHubAPIでREST APIとGraphQLの比較

2024/09/14に公開

はじめに

GraphQLってなに?という状態でしたので調べました。
GitHubAPIを例にREST APIとGraphQLの比較をしました。
なんとなくイメージが掴むのが目的です。

REST APIとは

REST APIは、リソースごとにエンドポイントを定義し、HTTPメソッド(GET, POST, DELETE, PUT など)を使って操作を行います。各リソース(例: usersrepos)にアクセスするための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とは

https://graphql.org/

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": "複数のフリマサイトを一括で検索するアプリ"
}
]
}
}
}
}

こちらで実行できます。
https://docs.github.com/ja/graphql/overview/explorer

特徴:

  • 必要なデータだけを取得: クライアントがクエリを作成するため、不要なデータがレスポンスに含まれない。これにより、通信コストや処理の無駄が減る。
  • 柔軟なデータ取得: 一度のクエリで複数のリソースを指定できるため、REST APIのように複数回リクエストする必要がない。たとえば、上記のクエリでユーザー情報とそのリポジトリ情報を一度に取得できる。
  • 型指定が可能:
    もし「名前は文字列、年齢は整数」と決めてあるのに、「名前に数字を入れる」といった間違いをしようとすると、エラーが発生してそのミスを防いでくれる。
    やり取りするデータの型がはっきりしているので、間違いが少なくて安心。

GraphQLの問題点:

  1. 学習コスト:
    • スキーマベースでクエリを組み立てる必要があるため、GraphQLのスキーマやクエリ構造に対する理解が必要。
  2. セキュリティリスク:
    • クライアントが自由にクエリを組み立てられるため、大規模なクエリを意図せず実行してサーバーの負荷が高くなる可能性がある。また、過剰に詳細な情報を要求されるリスクもある。
  3. クエリの最適化:
    • クエリの作り方次第でパフォーマンスが左右される。特に複雑なクエリでは、サーバーサイドの処理が複雑になりやすい。

REST APIとGraphQLの主な対比

項目 REST API GraphQL
エンドポイント リソースごとにエンドポイントを定義 単一のエンドポイント
データ取得方法 エンドポイントに対してHTTPメソッドを使って操作 クライアントがクエリを組み立てて必要なデータだけを取得
必要なデータ量 固定されたレスポンスで不要なデータも含まれることが多い 必要なデータだけを取得
複数リソース取得 複数エンドポイントへのリクエストが必要 一度のクエリで複数リソースを取得
型安全性 型に依存せず、APIドキュメントからの解釈が必要 スキーマによって型が保証される
パフォーマンス 無駄なデータが含まれることで通信量が増える可能性がある 不要なデータがないため通信量が減少し、パフォーマンス向上
学習コスト 比較的低い(一般的に普及している) 高い(スキーマ、クエリ構造の理解が必要)

おわりに

GraphQLはNetflix、メルカリ、楽天、Airbnb、Twitter、GitHub,AmazonWEBサービス、スタディサプリ等の大きなサービスで使われているみたいです。

参考

https://docs.github.com/ja/graphql

https://zenn.dev/hsaki/articles/github-graphql

https://zenn.dev/shunjuio/articles/e5515872871534

https://engineering.mercari.com/blog/entry/20220303-concerns-with-using-graphql/

Discussion