🎃

GraphQLとは?RESTと比較した特徴やメリット・デメリットを学ぶ

2024/05/13に公開

GraphQLとは?

GraphQLはAPI向けに作られたクエリ言語。
クエリ言語の代表例としてSQLがあるが、GraphQLはAPIに対してクエリ操作で問い合わせを行う。

GraphQLの歴史

  • 2012年 Facebookによって開発される
  • 2015年 FacebookがGraphQLをオープンソース化
  • 2019年 GraphQL Foundationが設立され、GraphQLの開発がGraphQL Foundationに移管

※GraphQL Foundationには2024年5月現在Airbnb、aws、atlassian、Microsoft、IBM等の企業が参加している

REST APIと比較したGraphQLの特徴

1. APIのリクエストは特定のURLに対してクエリをPOSTする

REST APIの場合

リソース毎のURLに対して、GET、POST、PUT、DELETE等のリクエストメソッドでリクエストする。

GET /users
GET /users/1
POST /users
PUT /users/1
DELETE /users/1

GraphQLの場合

特定のURLに対してクエリをPOSTする。

POST /graphql

2. サーバーに対して必要な分だけ過不足無くデータを取得できる

REST APIの場合

リソース単位でAPIを作成するため、画面内で使わないカラムもレスポンスに含まれてしまい、通信容量の増加や性能の悪化に繋がりやすい。

例) ユーザー一覧を取得する場合
GET /api/v1/users
{
  "users": [
     {
      "id": 1,
      "name": "taro",
      "email": "taro@example.com",
      "status": "active",
      "created_at": "2024-01-01 00:00:00",
      "updated_at": "2024-01-01 00:00:00"
    },
    {
    ...
    }
  ]
}

GraphQLの場合

画面の表示に必要な項目のみクエリで取得するため、レスポンスには無駄なカラムが含まれない。

例) ユーザー一覧を取得する場合
query {
  users {
    id
    name
  }
}
{
  "data": {
    "users": [
      {
        "id": 1,
        "name": "taro"
      },
      {
        ...
      }
    ]
  }
}

3. 1度のリクエストで関連するデータをまとめて取得できる

REST APIの場合

画面の表示に必要なリソースの数分、APIのリクエストが発生する。

例) 記事一覧とカテゴリ一覧を取得する場合
GET /api/v1/posts
GET /api/v1/categories

GraphQLの場合

一度のリクエストで複数のリソースを同時に取得するようなクエリを書くことが出来る。

例) 記事一覧とカテゴリ一覧を取得する場合
query {
  posts {
    id
    title
  }
  categories {
    id
    name
  }
}

4. スキーマによってリクエストやレスポンスの型が決まっている

REST APIの場合

リクエストはクエリパラメータ、レスポンスはJSONやXML等でやり取りされており、型の取り決めは特に無い。

例) カテゴリをもとに記事一覧を取得
GET /api/v1/posts?category=food

GraphQLの場合

スキーマによってリクエストやレスポンスの型は全て決められている。

例) カテゴリをもとに記事一覧を取得

リクエストおよびレスポンスのスキーマ

type Author {
  id: Int!
  firstName: String!
  lastName: String!
}

type Post {
  id: Int!
  title: String!
  category: String!
  author: Author
}

input GetPostsRequest {
  category: String
}

type Query {
  posts(input: GetPostsRequest): [Post]
}

クエリ

query {
  posts(input: { category: "food" }) {
    id
    title
    category
    author
  }
}

また、フロントエンドがTypeScriptの場合はgraphql-code-generatorを利用することでスキーマをもとに自動でTypeScriptの型定義を作成することが可能。

GraphQLのメリット/デメリット

メリット

  • クエリ言語による柔軟なリクエストと最小限のレスポンス
    • オーバー/アンダーフェッチングが起きにくい
  • 一度のリクエストで画面表示に必要な全ての情報を取得できる
    • サーバーへのリクエスト数を減らすことができる
  • スキーマによる型定義ができる
  • graphql-code-generator等の関連ツールが充実している

デメリット

  • 学習コストが高い
    • Schema、Query、Mutation、Resolver、Dataloader等覚えることが多い
  • クエリで柔軟なリクエストが出来る分、セキュリティ上の考慮が必要
    • スキーマが分かれば任意の項目を取得できたり、一度のクエリで取得する項目数や階層等に制限を設けないと攻撃に使われる可能性がある
  • 必要な項目を一つのリクエストで取得する設計になるため、レスポンスまでに時間がかかる
    • REST APIの場合はリソース単位でリクエストするため、一つ一つのレスポンスは速く、コンポーネント毎に取得した項目から表示することができるが、GraphQLでは表示までに時間がかかってしまう
  • HTTP/2によりリクエスト数を節約することの恩恵が少なくなった
  • レスポンス項目がクライアント依存になるため、サーバー側でキャッシュがしにくい
  • エンドポイントが /graphql のみのため、分析がしにくい
    • エンドポイント毎のパフォーマンス分析やObservability等のモニタリングが難しくなる
  • 画像や動画等のファイルアップロードの扱いが難しい
    • バイナリをbase64エンコードして文字列に変換したり、multipart/form-data でGraphQLのクエリを送信するような実装を考える必要がある

まとめ

この記事ではGraphQLの概要をざっくり紹介しました。

メリット、デメリットでは結果的に今回はデメリットの方が多くなってしまいましたが、私自身は個人開発のアプリでGraphQLを使っているため、GraphQLが向いているかはGraphQLへの理解度とプロダクトの要件によるのかなと思います。

株式会社Inner Resource

Discussion