🎃
GraphQLとは?RESTと比較した特徴やメリット・デメリットを学ぶ
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のクエリを送信するような実装を考える必要がある 
 - バイナリをbase64エンコードして文字列に変換したり、
 
まとめ
この記事ではGraphQLの概要をざっくり紹介しました。
メリット、デメリットでは結果的に今回はデメリットの方が多くなってしまいましたが、私自身は個人開発のアプリでGraphQLを使っているため、GraphQLが向いているかはGraphQLへの理解度とプロダクトの要件によるのかなと思います。
Discussion