📈

GraphQLを学ぶ その1

2023/01/03に公開

これは何

GraphQLとは

  • SQLのCRUD操作の考え方をインターネットに適用している
    • 例えばUserテーブルを取得したい場合は下記のクエリを記述するが...
      SELECT name,age FROM User where name = 'hoge';
      
    • GraphQLではSELECTの時にQueryを使う
      query {
          User(name: "hoge") {
              name
              age
          }
      }
      # 結果
      {
          "data": {
              name: "hoge"
              age: 26
          }
      }
      
  • 必要な情報だけを取得する事が出来るためQueryがシンプルになる
  • 個人的にはカンマを書かなくて良いのが楽だと感じる

GraphQLで値を取得する 基本

  • 基本は前述のQueryの書き方
    • QueryはGraphQLの型の一つでルート型
    • 波括弧で囲まれたブロックは選択セット
      • 選択セットで指定できるフィールドはQuery型として定義されている(どこで?というのはまた後ほど...)
    • エイリアスを指定する事でレスポンスのフィールド名を任意のものに置き換えられる
    • フィルタリングをしたい場合はクエリ引数を利用する
    • GraphQLのレスポンスには大きく下記のパターンの型になる
      • 5つのスカラー型
        • Int
        • Float
        • String
        • Boolean
        • ID
      • オブジェクト型
        • JSONオブジェクトで規定する
query { #<-ルート型、このブロックは選択セット
    User(name: "hoge") { #<-クエリ引数
        name
        user_age: age #<-エイリアスの設定
        userHobby { #<-hogeユーザーに紐づく趣味
            hobby_name: name
        }
    }
}
# 結果
{
    "data": {
        name: "hoge" #<-String
        user_age: 26 #<-Int
        userHobby: [
            {
                hobby_name: "mountain climbing"
                hobby_name: "cycling"
                hobby_name: "snowboarding"
            }
        ]
    }
}

GraphQLで値を取得する ちょっと応用?

  • fragmentを使って冗長な書き方を改善する

    # 改善前
    query {
        User(name: "hoge") {
            name
            age
            status
            from
        }
        userHobby(name: "mountain climbing") {
            name
            difficulty
            inOrOut
            User {
                name
                age
                status
                from
            }
        }
    }
    # 改善後
    query {
        User(name: "hoge") {
            ...userInfo
        }
        userHobby(name: "mountain climbing") {
            name
            difficulty
            inOrOut
            ...userInfo
        }
    }
    fragment userInfo on User {
        name
        age
        status
        from
    }
    
  • 複数の型を持つオブジェクトを扱う

    • ユニオン型で複数の型を持つオブジェクトを取得する
      • 複数の型を持つオブジェクト、がどういう状況かよくわからなかった...。
      • という訳でググる
      • GraphQL スキーマ仕様: ユニオン型 (Union types) を定義する
        • IssueとPullRequestなど、同じ値を何らか持っている場合は便利そう
        • エラー表現は使いやすそう

        ユニオン型は、エラーを表現するためにも使用できます。 次の createBook は新しい書籍データを登録するための mutation ですが、登録に成功したときは Book オブジェクトを返し、失敗したときは各種エラーを表すオブジェクトを返します。

      • ユニオン型はオブジェクトの実態が異なる型になる
    • もう一つの方法、インターフェース型で取得する

その1 〆

  • GraphQLの本体はバックエンドの仕組みでは?と言う思いが拭えず、フロントエンド側でのメリットしかまだ感じられていない
  • SQLが好きなので、SQLの考え方を適用していると聞くとなんとなく理解する気持ちになった
  • マジで全く理解していなかったのだけどなんとなくでGraphQLを使った現場でバックエンドを半年もやれてきてしまったのやばいな...(それくらい馴染み易いという事なのかもしれない)
  • 最後のユニオン型とインターフェース型は実践例があまり浮かばなかったので改めて詳しく見てみる

Discussion