LoginSignup
0
0

More than 5 years have passed since last update.

graphql-rubyのメモ(queryのみ)

Last updated at Posted at 2019-02-02

仕事でgraphqlを使うことになったので、自分なりに勉強したメモを公開します。
この記事ではgraphql-rubyというgemを使い、自分で定義した型のデータをデータ取得用のリクエストを発行して取得するところまでの超基本のところまでのメモとなります。
Hello Worldに毛が生えた程度のものとなります。

前提

  • ruby 2.5.1p57
  • rails 5.1.6.1
  • 上記の環境でrails newで動作確認用のrailsプロジェクトは作成済の状態
  • ちなみにGraphQLについての知識はこの記事を書く前の時点でGraphQLという便利なインターフェースがあるらしい程度の知識

セットアップ

インストール

Gemfileに以下を追加し、bundle installする。

gem 'graphql'

graphql関連の基本的なファイルを生成

rails g graphql:install

その後、Gemfileに以下のgemが追加されるので、bundle installする

graphiql-rails

この状態で動作確認してみる

http://localhost:3000//graphiql
にアクセスし、一番左のところに以下のクエリを入力し、実行ボタンを押す

{
  testField
}

以下のような結果が返ってきたら、成功。

{
  "data": {
    "testField": "Hello World!"
  }
}

スキーマについて

上記のクエリに対して、以下のところで反応している模様。この部分をスキーマと呼ぶらしい。
ここでクエリの各項目(どうやらfieldと呼ぶらしい)が指定された時の動作を指定する。
例えば、下の自動生成したスキーマではクエリ内でtestFieldが指定されたら、test_fieldメソッドが呼ばれ、メソッドの返却値がクリエの結果として返却される。

app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    # TODO: remove me
    field :test_field, String, null: false,
      description: "An example field added by the generator"

    def test_field
      "Hello World!"
    end
  end
end

クエリに指定されたfieldが何を返却するかを定義しているのが、query_type.rbということを理解。
今回はクエリにtest_fieldを含んでいるので、このクラス内のtest_fieldが実行され、"Hello World!"が返却される。

確認用にちょっと改造

スキーマにもう1つfieldを追加して、動作確認してみる。

app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    # TODO: remove me
    field :test_field, String, null: false,
      description: "An example field added by the generator"

    field :test_field2, String, null: false,                  # 追加
      description: "An example field added by the generator"  # 追加

    def test_field
      "Hello World!"
    end

    def test_field2     # 追加
      "test2"
    end
  end
end

http://localhost:3000//graphiql
で以下のクエリを投げる。

{
  testField,
  testField2
}

期待どおり、testField2として"test2"が返却された。

{
  "data": {
    "testField": "Hello World!",
    "testField2": "test2"
  }
}

graphqlのオブジェクトを生成

次はオブジェクトを定義してみる。
いわゆる型のようなものだと理解。

rails g graphql:object Post title:String rating:Int

このコマンドを実行すると以下のファイルが生成される

app/graphql/types/post_type.rb
module Types
  class PostType < Types::BaseObject
    field :title, String, null: true
    field :rating, Integer, null: true
  end
end

クエリで型を指定した時に値が返却されるようにスキーマを書き換える

app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :post, PostType, null: true do  # ここでPostTypeを指定
      description "Find a post by ID"
    end

    def post    # ここでpostが指定された時に返却する値を設定
      {
        "title" => "test_title",
        "rating" => 3,
      }
    end
  end
end

以下のクエリを投げる

{
  post {
    title
    rating
  }
}

投げると以下のような内容が返却される。

{
  "data": {
    "post": {
      "title": "test_title",
      "rating": 3
    }
  }
}

型にパラメータを指定できるようにする

idを指定してidに関連した値を取得する、というのはよくあるケースだと思うので、idを指定できるように改造。

まずはidを受け取れるように型にidを追加

app/graphql/types/post_type.rb
module Types
  class PostType < Types::BaseObject
    field :id, ID, null: false        # 追加
    field :title, String, null: true
    field :rating, Integer, null: true
  end
end

次はスキーマでもidを受け取れるように改造

app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :post, PostType, null: true do
      description "Find a post by ID"
      argument :id, ID, required: true      # 追加
    end

    def post(id:)     # idを引数で受け取れるようにする
      {
        "id" => id,                     # idをそのまま返却
        "title" => "test_title_#{id}",  # 動作確認用にIDをtitleに含める
        "rating" => 3,
      }
    end
  end
end

以下のようなスキーマを投げる

{
  post(id: 11) {
    id
    title
    rating
  }
}

すると以下の値が返却されてくる。

{
  "data": {
    "post": {
      "id": "11",
      "title": "test_title_11",
      "rating": 3
    }
  }
}

今回はスキーマ内でほぼ固定値のハッシュを返却しているが、実際にはここでidを元に何かを取得する処理を呼び出すような感じになるハズ。

IDを指定しないクエリを投げると・・・

スキーマ内で'required: true'となっているので、バリデーションが行われてエラーとなるハズ。
確認してみる為に以下のクエリを投げる。

{
  post {
    id
    title
    rating
  }
}

返却値。やっぱり、エラーとなった。

{
  "errors": [
    {
      "message": "Field 'post' is missing required arguments: id",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "fields": [
        "query",
        "post"
      ]
    }
  ]
}

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0