RailsでGraphQLを使う
結構使いやすくなっていたので紹介
セットアップ
# Gemfile gem 'graphql'
rails generate graphql:install
まず導入 基本的な構成と、graphiql(GraphQLのクライアントをRailsにマウントするやつ)が入る
http://localhost:3000/graphiql
サンプルフィールドが用意されているのでクエリを叩くと、結果が得られる。
こんなかんじ。
ActiveRecordとつなげる
Railsで使うからにはGraphQLのObjectとRailsのモデルを繋げなければいけません。 つなぐために
GitHub - goco-inc/graphql-activerecord
このGemを使います。
rails g model Book name:string
こんなモデルを予め作っておいてください。
# Gemfile gem 'graphql-activerecord'
bundle install
レコード作成
まずはBookモデルに対応したBookTypeを作ります。
# app/graphql/types/book_type.rb Types::BookType = GraphQL::ObjectType.define do name "Book" backed_by_model :books do attr :name end end
次にBookを新たに作成するためのMutationを定義します。
# app/graphql/mutations/create_book.rb Mutations::CreateBook = GraphQL::Relay::Mutation.define do name "CreateBook" return_field :book, Types::BookType input_field :name, !types.String mutator_definition = GraphQL::Models.define_mutator(self, Book, null_behavior: :leave_unchanged) do attr :name end resolve ->(obj, args, ctx) { { book: Book.create(name:args[:name]) } } end
あとは、このMutationを
App名Schemaに認識させます。
# app/graphql/types/mutation_type.rb Types::MutationType = GraphQL::ObjectType.define do name 'Mutation' field :CreateBook, field: Mutations::CreateBook.field end
# app/graphql/アプリ名_schema.rb アプリ名Schema = GraphQL::Schema.define do query(Types::QueryType) mutation(Types::MutationType) # 追加 lazy_resolve(Promise, :sync) instrument(:query, GraphQL::Batch::Setup) instrument(:field, GraphQL::Models::Instrumentation.new) end
これで叩ける用にはなりました。
問題なければDBにレコードが作成されているはずです。
queryを使う。
先程BookTypeは作ってしまったので、QueryTypeを記述するだけです。
# app/graphql/types/query_type.rb Types::QueryType = GraphQL::ObjectType.define do name "Query" field :book, Types::BookType do description "An example field added by the generator" argument :id, !types.ID resolve ->(obj, args, ctx) { Book.find(args[:id]) } end end
関連レコードも引っ張ってくる
これだけだとつまらないので関連データもとってこれるようにしたいと思います。 デモ用モデルとして「登場人物」を新たに作ります。
rails g model Character name:string book:references
次に CharacterTypeを定義します。 ちなみに、
rails g graphql:object Character
で作ることも出来る。
# app/graphql/types/book_type.rb Types::BookType = GraphQL::ObjectType.define do name "Book" backed_by_model :books do attr :name has_many_array :characters # 追加 end end
今日の雑記はgraphql-activerecord - あのにのに
でも書いたけど Typeの定義の仕方によっては一手間必要・
できたできた。