はじめに
GraphQLとは何か等の話は割愛しており、実装に関する話のみを行っております。
はじまり
仕事でGraphQLを使い始めたので勉強もかねて簡単なプログラムを作ろうと思いました。
(参考) 以下の環境に対して実装を行っています。
Ruby: 3.1.2
Rails: 7.0.3
graphql: 2.1.7
graphiql-rails: 1.9.0
Gem: GraphQLについて
GraphQL RubyというGemを使用します。
バージョン履歴を見ると毎月更新されるくらい活発に更新が行われています。
他にもGraphiQL-Railsと言われる GraphiQL IDE
を組み込めるGemも追加しています。
実装してみる
Bookを返却するスキーマを作成します。
- Bookモデル
カラム名(日本語) | カラム名(英語) | 型 |
---|---|---|
書名 | name | string |
著者 | author | string |
出版日 | publish_at | date |
金額 | amount | integer |
実装(GraphQL周り)
実際に組み込んで実装に入っていこうと思います。
Getting Started を見ながら作業をしていきます。
1.Gemfile
に GraphQL
を追加
- Gemfile
gem 'graphql'
group :development do
gem 'graphiql-rails'
end
GraphiQL-Rails
は開発環境でのみ実行できれば良いのでdevelopment
に定義しています。
2.インストール作業を行う
bundle install
rails g graphql:install
3.スキーマを定義する
- 型
app/grahpql/types/book_type.rb
を定義 - object type生成
bin/rails g graphql:object Book
# frozen_string_literal: true
module Types
class BookType < Types::BaseObject
field :title, String, null: false
field :author, String, null: false
field :publication_at, GraphQL::Types::ISO8601Date, null: false
field :amount, Integer, null: false
end
end
(注意)使用できる型については typesを参照
4.クエリを定義する
- クエリ
app/graphql/types/query_type.rb
を定義
# frozen_string_literal: true
module Types
class QueryType < Types::BaseObject
# 全件取得用
field :books, [BookType], null: false
def books
Book.all
end
# 対象レコード取得用
field :book, BookType do
argument :id, ID
end
def book(id:)
Book.find(id)
end
end
end
5.mutationをコメント化
今回は query
しか作成していないため mutation
をコメントアウトしないと動作しないようになってると思います。
(注意)mutation
実装時にこのコメントアウトを解除する必要があります。
- app/graphql/schema.rb(変更前)
# frozen_string_literal: true
class Schema < GraphQL::Schema
mutation(Types::MutationType)
query(Types::QueryType)
#(省略)
end
- app/graphql/schema.rb(変更後)
# frozen_string_literal: true
class Schema < GraphQL::Schema
# mutation(Types::MutationType)
query(Types::QueryType)
#(省略)
end
6.GraphQLを実行する
schema: books
を実行
schema: book(id)
を実行
実装してみて
単純なデータを返却する内容だったため割と簡単に実装することができました。
実際のWebサービスではDBのカラム保存値そのままを直接返せば良いって要求だけで済むことがあまりないため、色々と出力用の加工ロジックが増えたり、関連モデルを利用したフィールドも増えたりと複雑な内容になると思います。
引き続き勉強していこうと思います!