GraphQLについてまとめてみた


GraphQLとは

Facebookにより開発された、APIのためのクエリ言語であり、既存のデータを使用しクエリを実行するためのランタイム
GraphQLは、API内のデータの完全で理解可能な説明を提供し、クライアントに必要なものだけを正確に要求する力を与え、APIの長期的な発展を容易にし、強力な開発者ツールを有効にする (翻訳)
GraphQL

クエリ言語とスキーマ言語

GraphQLは、一般的にクエリ言語とスキーマ言語から構成される
クエリ言語(フロント側)は、GraphQL APIのリクエストのための言語であり、データ取得に関連するquery、データ更新に関連するmutation、サーバサイドからのイベント通知を行うsubscriptionの3種類がある
一般的にはqueryとmutationを利用する

スキーマ言語(サーバー側)は、GraphQL API の仕様を記述するための言語であり、記述したスキーマに従ってレスポンスを生成する

REST GraphQL
取得 GET Query
作成 POST Mutation
更新 PUT Mutation
削除 DELETE Mutation

(GraphQLはQueryもMutationもPostでやりとりをしているが、わかりやすいようにRESTに合わせている)

フィールド

クエリで取得できるフィールドとして、スカラタイプとオブジェクトタイプの2種類が存在する
GraphQLでは、以下の5種類に対応している
- Int
- Float
- String
- Boolean
- ID (String)

また、オブジェクト対応は1つ以上のフィールドを含んだグループで、JSON
の入れ子として表現される

エンドポイント

GraphQLのサーバー側の処理の流れ

  1. スキーマ等の設定
  2. query/mutationの判別
  3. variables(input)が必要ならそれの判定
  4. query/mutationの各リクエストに対するresolverの割り当て
  5. resolverで、細かい処理、値の返却
  6. 要求返却値に対しての処理

などなど、全て実装する必要がある
→ 手動での実装は辛い 
→ gqlgenなど利用して、ボイラープレートコードを自動生成

簡単な例

schema
type Query {
    docs: [Document!]!
}
type Document {
    id: ID!
    title: String!
    description: String!
    file: String!
}

このスキーマに対して、クエリを書くとすると、

query
query {
    docs {
        id
        title
    }
}

となる。これは、docsのidとtitleを取得するという意味になる。これにdescriptionやfileなどの情報が欲しい場合は、そのように記述することでデータを取得することができる。
また複数のschemaに対しては、

schema
type Query {
    user(username: String!): User!
}
type User {
    id: ID!
    username: String!
    password: String!
    email: String!
}
query
query {
    user(username:"your name") {
        id
        username
        email
    }
    docs {
        id
        title
        description
    }
}

のように、複数のresolverに対してqueryを投げることができ、リクエストの回数を減らすこともできる

メリット

  • 必要な情報しか通信が行われない
  • エンドポイントが1つですむ
  • リクエストの回数を減らすことができるかも
  • 型の検証を行いながらリクエストできる
  • バックエンド側の調整なしに、フロント側で情報を選択し、取得することができる

デメリット

  • サーバー側の処理の実装が難しい
    • スキーマの全てのパターンの実装が必要とになってくる
    • スキーマを元に、自動で枠組みを生成してくれるライブラリなどを利用する場合もある
      • gqlgenやgraphql-goなど
  • データのキャッシュがめんどくさい
    • RESTのキャッシュは、エンドポイントに応じてキャッシュの処理を行う
    • GraphQLの場合、一意のIDを定義し、正規化されたキャッシュを構築する。クライアントが構築されたオブジェクトを参照するクエリを発したら、キャッシュを返すという仕組みになっている

備考

間違っている内容や追加指摘など、ございましたら教えていただけると幸いです。