• トップ
  • ブログ一覧
  • GraphQL開発で覚えておきべき機能を紹介!
  • GraphQL開発で覚えておきべき機能を紹介!

    はっと(エンジニア)はっと(エンジニア)
    2023.12.04

    IT技術

    はじめに

    本日はGraqhQL開発で覚えておきべき機能についていくつか解説していきます。
    GraphQL開発に始めてアサインされた方や紹介する機能を使用していないという方などのお役に立てれば幸いです。

    ※ railsで「GraphQL Ruby」を使用して説明します。

    ご紹介する内容

    フィールドの「description」について

    フィールドのデフォルト値の設定方法

    リゾルバの種類について

    フィールドの「description」について

    「description」とは、フィールドがなにを表すデータなのかを記述する説明文になります。
    desctiptionを記述するとGraphQLツールでスキーマを閲覧する際に内容が表示され、フィールドの目的や使用方法を理解するのに役立ちます。

    コードを読む際も、「あ〜こういうデータなのか」といった予備知識を持った状態でコードを読むことができ、コードリーディング時間を大幅に削減できます。
    実際に「description」を定義し、GraphQLツールで表示を確認してみましょう。


    例えば「全てのユーザー情報を取得する」usersクエリがあるとします。
    ユーザー情報はUserTypeとして「description」は以下のように定義することができます。

    1module Types
    2  class UserType < Types::BaseObject
    3    field :id, ID, "ユーザーID", null: false
    4    field :first_name, String, "名前", null: false
    5    field :last_name, String, "苗字", null: false
    6    field :is_married, Boolean, "結婚しているかどうかを示す", null: false
    7  end
    8end

    QueryTypeでは以下のように定義します。
    usersメソッドはusersフィールドのリゾルバです。Userモデルの全データを返しています。

    1module Types
    2  class QueryType < Types::BaseObject
    3    field :users, [UserType], "全てのユーザー情報を取得する", null: false
    4
    5    def users
    6      User.all
    7    end
    8  end
    9end

    これをGraphQLツールのGraphiQL-Railsで表示してみると以下のように表示されます。


    このようにスキーマの構造を理解する助けになるため、ぜひ全フィールドに追加してみましょう。(※後から全て追加するのはかなり大変です)

    フィールドのデフォルト値の設定方法

    特定のフィールドの値がない場合にカスタムリゾルバを使用することでデフォルト値を設定することができます。
    例えば以下のUserTypeのisMarriedフィールドに値がない場合はどうなるでしょうか?

    1module Types
    2  class UserType < Types::BaseObject
    3    field :id, ID, "ユーザーID", null: false
    4    field :first_name, String, "名前", null: false
    5    field :last_name, String, "苗字", null: false
    6    field :is_married, Boolean, "結婚しているかどうかを示す", null: false
    7  end
    8end

    クエリを叩いてみると、以下のようにisMarriedが万が一nullの場合「isMarriedはnull許可していないけどnullになってますよ」とエラーが発生してしまいます。

    isMarriedをnull許容に設定すれば、エラーは出ませんが、isMarriedの値が存在する前提で処理をしたいといった要件がある場合は、デフォルト値を設定してみましょう。
    isMarriedがnullであれば、「false」を返す設定をしてみます。

    デフォルト値の設定例

    1module Types
    2  class UserType < Types::BaseObject
    3    field :id, ID, "ユーザーID", null: false
    4    field :first_name, String, "名前", null: false
    5    field :last_name, String, "苗字", null: false
    6    field :is_married, Boolean, "結婚しているかどうかを示す", null: false
    7
    8    // isMarriedのカスタムリゾルバ
    9    def is_married
    10      // isMarriedに値があるかをチェックし、存在すればその値を、存在しなければ「false」を返す
    11      object.is_married.present? ? object.is_married : false
    12    end
    13  end
    14end

    UserTypeのclass内にフィールド名と同名のメソッドを定義すれば、カスタムリゾルバとして、個別にフィールドの処理をしてくれます。
    この時に出てくるobjectは、isMarriedの上の階層のusersフィールドのリゾルバの「User.all」で取得したUserモデルのデータが入ってきます。

    1module Types
    2  class QueryType < Types::BaseObject
    3    field :users, [UserType], "全てのユーザー情報を取得する", null: false
    4
    5    def users
    6      User.all
    7    end
    8  end
    9end

    このように上位階層のリゾルバの処理結果が、下の階層のリゾルバに渡され、その値を参照することでフィールドごとに個別設定をすることができます。
    デフォルト値を設定したことで以下のようにエラーにならずに処理結果を受け取ることができました。

    リゾルバの種類について

    リゾルバには以下のように2種類のリゾルバがあります。

    1. カスタムリゾルバ
    2. デフォルトリゾルバ

    カスタムリゾルバとは、特定のフィールドや操作に対して明示的に定義する関数です。
    usersフィールドのusersメソッドがそれに当たります。

    1module Types
    2  class QueryType < Types::BaseObject
    3    field :users, [UserType], "全てのユーザー情報を取得する", null: false
    4
    5    def users
    6      User.all
    7    end
    8  end
    9end

    デフォルトリゾルバとは、特にカスタムリゾルバが定義されていない場合にGraphQLシステムによって自動的に使用されるリゾルバです。
    User.allによって、UserTypeのフィールドには特にリゾルバを設定しなくても値を取得することができました。
    これは内部でデフォルトリゾルバが適用されているためになります。

    デフォルトリゾルバは以下のような特徴があります。

    オブジェクトにプロパティやメソッドがあれば、その結果を返す

     

    つまり、UserTypeのフィールドそれぞれに個別のリゾルバの設定を書かなくても、Userモデルが同名のプロパティやメソッドを持っていれば、その結果を返してくれるということになります。
    この振る舞いを使用する例を見てみましょう。

    UserTypeに「fullNameフィールド」を追加します。

    1module Types
    2  class UserType < Types::BaseObject
    3    field :id, ID, "ユーザーID", null: false
    4    field :first_name, String, "名前", null: false
    5    field :last_name, String, "苗字", null: false
    6    field :is_married, Boolean, "結婚しているかどうかを示す", null: false
    7    field :full_name, String, "完全な名前(苗字 + 名前)", null: false // 追加
    8
    9    def is_married
    10      object.is_married.present? ? object.is_married : false
    11    end
    12  end
    13end

    次にUserモデルにfull_nameメソッドを定義します。

    1class User < ApplicationRecord
    2  // 苗字 + 名前の値
    3  def full_name
    4    last_name + first_name
    5  end
    6end

    クエリを実行すると、full_nameメソッドの処理結果を受け取ることができました。

    このようにUserTypeにUserモデルに存在しないフィールドを追加した場合でも、Userモデルにメソッドを追加するだけでフィールドを拡張したり、特定のオブジェクトタイプの処理を独自クラスで行ったりすることができます。
    ぜひこの振る舞いは覚えておきましょう。

    最後に

    今回はGraqhQL開発で覚えておきべき機能について紹介させていただきました。
    私自身GraqhQLについて詳しくない時、「description」をほとんど書いておらず、後から追加するのに苦労しました。
    リゾルバに関しても「そんな振る舞いがあったの知らなかった...」という方がいらっしゃいましたら少しでも参考なれば幸いです。

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    はっと(エンジニア)

    はっと(エンジニア)

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background