初めに(Qiita版)
この記事は私のブログから移植したものです。
内容は同じですが、ブログの方もよろしくお願いします。
ブログの方でGoodボタン押してくれたら嬉しいな(小声)
初めに
この記事はGraphQLガイドの中から、初心者がある程度GraphQLを理解するのに必要な要素をまとめ、解説するものです。
記事内のすべてのコードはRubyで書かれており、RailsアプリにGraphQLを組み込むというシチュエーションが前提です。
なお、GraphQLのインストールそのものについてはこの記事では触れません。
GraphQLの最低限の概要
GraphQLのAPIには大きく分けて2種類あります。
”Query"と”Mutation"です。
RailsにGraphQLをインストールした段階で、'app/graphql/my_app_name_schema.rb(XXXは自分のアプリ名)' というファイルが生成されます。
class MyAppNameSchema < GraphQL::Schema
mutation(Types::MutationType)
query(Types::QueryType)
end
CURDの内、QueryがReadを担当し、MutationがCreate, Update, Deleteを担当します。
QueryType
'app/graphql/types/query_type.rb' を見てください。
以下のような感じになっていると思います。
module Types
class QueryType < Types::BaseObject
field :test_field, String, null: false,
description: "An example field added by the generator"
def test_field
"Hello World!"
end
end
end
test_field
これが自動生成されたAPI(Query)です。
コンソールで'rails s'して、ブラウザから'localhost:3000/graphiql'にアクセスすると、'test_field'というAPIのみが使えることが解ると思います。
grapiql とは
railsにGraphQLをインストールすると自動的に生成されるテスト用のページです。
詳しい使い方は調べればいくらでも出てくるので省きます。
ちなみに私はこのテスト用のページの存在だけでもGraphQLを使うメリットしては十分だと考えています。
フロントエンドの人に「このページ見て」ってURLを渡せばどんなAPIがあるのか一目瞭然。
しかもコードから生成されているのでエクセル仕様書と違って絶対に陳腐化しない!
'rails s'をやり直さなくてもブラウザリロードで変更が反映される点も個人的にはポイント高いです。
では話を戻します。
RailsアプリのModelに対応する
アプリのDBスキーマ
まずは、RailsアプリのSchemaを紹介します。
この辺はご自身のアプリに合わせて読み替えてください。
ActiveRecord::Schema.define(version: 2019_05_12_151517) do
create_table "books", force: :cascade do |t|
t.text "title"
t.string "author"
t.integer "review_count"
t.string "review_average"
t.string "books_genre_id"
t.integer "page"
end
create_table "genre_groups", force: :cascade do |t|
t.string "books_genre_id"
t.string "books_genre_name"
end
create_table "genres", force: :cascade do |t|
t.string "books_genre_id", null: false
t.string "books_genre_name", null: false
t.integer "genre_group_id"
end
end
GenreGrouprとGenreは1対多の関係にあります。
'小説'というGenreGroupの中に'童話', 'フィクション', 'SF'などのGenreがあるイメージです。
class Genre < ApplicationRecord
belongs_to :genre_group
end
# genre_group.rb
class GenreGroup < ApplicationRecord
has_many :genres
end
GenreGroupモデルのAPIを作成
GenreGroupTypeを定義します。
※GenreGroupTypeそのものはAPIではありません。
module Types
class GenreGroupType < Types::BaseObject
field :id, ID, null: false
field :books_genre_id, String, null: false
field :books_genre_name, String, null: false
end
end
IDやStringが各fieldの戻り値の型で、'null: false'は'non-null'を表します。
戻り値として使えるのは以下のScalarsです。
- String
- Int
- Float
- Boolean
- ID
- ISO860DateTime
- JSON
自分で型を定義することも可能で、Enumsと呼ばれるようです。
ここでは解説せず、公式ガイドを紹介するにとどめます。
https://graphql-ruby.org/type_definitions/enums
APIの作成
QyeryTypeに以下のように追記します。
※':test_field'は消しました。
module Types
class QueryType < Types::BaseObject
field :genre_groups, [Types::GenreGroupType], null: false,
description: 'ジャンルグループをすべて取得する'
def genre_groups
GenreGroup.all
end
end
end
再びgraphpiqlをブラウザでリロードし、確認してください。
QueryのAPIに'genreGroups'が追加されています。
※'genre_groups'ではなく。
ちなみに、fieldの宣言部分を'field :genreGroups'と書くと、エラーが出ます。
GenreGroupTypeで作成したfieldとは異なり、こちらはAPIのエンドポイントのように働きます。
つまり、'field :my_api'と書けば、フロントアプリケーションは'my_api'というAPIを叩くことになります。
まとめ
私見ですが、QueryTypeをMVCパターンでのController、〇〇TypeをModelとして考えるとそれぞれの役割がイメージしやすいと思います。
もっとfieldについて詳しく知りたい人は公式ガイドをチェックしてください。
https://graphql-ruby.org/fields/introduction.html