[GraphQL]最も簡単なチュートリアル

# 初めに（Qiita版）

この記事は<a href="https://ogutip.mixh.jp/wp/2019/06/01/graphql/">私のブログ</a>から移植したものです。
内容は同じですが、ブログの方もよろしくお願いします。
ブログの方でGoodボタン押してくれたら嬉しいな（小声）

# 初めに

<p>この記事は<a href="https://graphql-ruby.org/guides#fields-guides">GraphQLガイド</a>の中から、初心者がある程度GraphQLを理解するのに必要な要素をまとめ、解説するものです。</p>

<p>記事内のすべてのコードはRubyで書かれており、RailsアプリにGraphQLを組み込むというシチュエーションが前提です。<br> なお、GraphQLのインストールそのものについてはこの記事では触れません。</p>

# GraphQLの最低限の概要

<p>GraphQLのAPIには大きく分けて2種類あります。<br>
”Query"と”Mutation"です。</p>

<p>RailsにGraphQLをインストールした段階で、'app/graphql/my_app_name_schema.rb(XXXは自分のアプリ名)' というファイルが生成されます。</p>

```ruby:app/graphql/my_app_name_schema.rb
class MyAppNameSchema < GraphQL::Schema
  mutation(Types::MutationType)
  query(Types::QueryType)
end
```

<p>CURDの内、QueryがReadを担当し、MutationがCreate, Update, Deleteを担当します。</p>

# QueryType

<p>'app/graphql/types/query_type.rb' を見てください。<br> 以下のような感じになっていると思います。</p>

```Ruby: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

<p>これが自動生成されたAPI（Query）です。<br> コンソールで'rails s'して、ブラウザから'localhost:3000/graphiql'にアクセスすると、'test_field'というAPIのみが使えることが解ると思います。</p>

# grapiql とは

<p>railsにGraphQLをインストールすると自動的に生成されるテスト用のページです。<br>
詳しい使い方は調べればいくらでも出てくるので省きます。</p>

<p>ちなみに私はこのテスト用のページの存在だけでもGraphQLを使うメリットしては十分だと考えています。<br>
フロントエンドの人に「このページ見て」ってURLを渡せばどんなAPIがあるのか一目瞭然。<br>
しかもコードから生成されているのでエクセル仕様書と違って絶対に陳腐化しない！<br>
'rails s'をやり直さなくてもブラウザリロードで変更が反映される点も個人的にはポイント高いです。</p>

<p>では話を戻します。</p>

# RailsアプリのModelに対応する

## アプリのDBスキーマ

<p>まずは、RailsアプリのSchemaを紹介します。<br>この辺はご自身のアプリに合わせて読み替えてください。</p>

```Ruby:schema.rb
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
```

<p> GenreGrouprとGenreは1対多の関係にあります。<br> '小説'というGenreGroupの中に'童話', 'フィクション', 'SF'などのGenreがあるイメージです。</p>

```Ruby:genre.rb
class Genre < ApplicationRecord
  belongs_to :genre_group
end

# genre_group.rb
class GenreGroup < ApplicationRecord
  has_many :genres
end
```

## GenreGroupモデルのAPIを作成

<p>GenreGroupTypeを定義します。<br> ※GenreGroupTypeそのものはAPIではありません。</p>

```Ruby:app/graphql/types/genre_group_type.rb
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
```

<p>IDやStringが各fieldの戻り値の型で、'null: false'は'non-null'を表します。<br> 戻り値として使えるのは以下の<a href="https://graphql-ruby.org/type_definitions/scalars.html">Scalars</a>です。</p>

<ul><li>String</li><li>Int</li><li>Float</li><li>Boolean</li><li>ID</li><li>ISO860DateTime</li><li>JSON</li></ul>
<!-- /wp:list -->

<p>自分で型を定義することも可能で、Enumsと呼ばれるようです。<br> ここでは解説せず、公式ガイドを紹介するにとどめます。<br>https://graphql-ruby.org/type_definitions/enums</p>

## APIの作成

<p>QyeryTypeに以下のように追記します。<br> ※':test_field'は消しました。</p>

```Ruby:query_type.rb
module Types
  class QueryType < Types::BaseObject
    field :genre_groups, [Types::GenreGroupType], null: false,
      description: 'ジャンルグループをすべて取得する'
    def genre_groups
      GenreGroup.all
    end
  end
end
```

<p>再びgraphpiqlをブラウザでリロードし、確認してください。<br>
QueryのAPIに'genreGroups'が追加されています。<br>
　※'genre_groups'ではなく。</p>

<p>ちなみに、fieldの宣言部分を'field :genreGroups'と書くと、エラーが出ます。</p>

<p>GenreGroupTypeで作成したfieldとは異なり、こちらはAPIのエンドポイントのように働きます。<br>
つまり、'field :my_api'と書けば、フロントアプリケーションは'my_api'というAPIを叩くことになります。</p>

# まとめ

<p>私見ですが、QueryTypeをMVCパターンでのController、〇〇TypeをModelとして考えるとそれぞれの役割がイメージしやすいと思います。</p>

<p>もっとfieldについて詳しく知りたい人は公式ガイドをチェックしてください。<br>
https://graphql-ruby.org/fields/introduction.html</p>