コード譜投稿アプリを作る #3（railsにgraphql導入）

[←前回の記事](https://qiita.com/t_sekky/items/336c1fa8dd7a0f3d8f1b)

# GraphQLの導入経緯
当初は導入するつもりはなかったのですが、新しくジョインするところがRails＆GraphQLでバックエンドを実装しているらしいので練習がてら急遽導入することに決めました。
これまではshopifyのカートシステムのgraphQLAPIを使ってフロントを実装する、ということはやっていたので呼び出し側ではgraphQL使ったことがありますが、APIを作成したことはなかったので慣れておかないと…

GraphQLがどんなものかとか、REST APIとどう違うかなどは他に良い記事がいくつもあるので省略。


# GraphQLのインストール
GraphQL公式の[Rails用チュートリアル](https://graphql-ruby.org/getting_started)をみながら進めていきます。

まずはgemをダウンロード

Gemfileに追加して、
```:Gemfile
gem "graphql"
```
コマンド実行
```
$ docker-compose run --rm web bundle install
$ docker-compose run --rm rails g graphql:install
```

もう一度`bundle install`が必要な場合があるそうです。
```
$ docker-compose run --rm web bundle install
```

これでインストールが完了。

# 実装
今回はコード譜を`Score`というオブジェクトで表現したいと考えているので、そのテーブルを最初に作成します。


まずはテーブル作成。
持たせる属性はとりあえずtitleだけ

```
$ docker-compose run --rm web bundle exec rails g model Score title:string
$ docker-compose run --rm web bundle exec rails db:migrate
```

そしてGraphQLオブジェクトを以下のコマンドで作成。
最後に指定している`Score`と同名のテーブル（↑でつくったやつ）から型定義ファイルを作成してくれます。

```
$ docker-compose run --rm web rails g graphql:object Score
```

`/app/graphql/types/score_type.rb`が作成されます。
``` ruby:/app/graphql/types/score_type.rb
# frozen_string_literal: true

module Types
  class ScoreType < Types::BaseObject
    field :id, ID, null: false
    field :title, String
    field :created_at, GraphQL::Types::ISO8601DateTime, null: false
    field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
  end
end
```

特に指定していないのにちゃんと`title`も反映されていますね :thumbsup: 

`/app/graphql/types/query_type.rb`を編集。
schemaを定義します。いったんqueryだけ

``` rb:/app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add `node(id: ID!) and `nodes(ids: [ID!]!)`
    include GraphQL::Types::Relay::HasNodeField
    include GraphQL::Types::Relay::HasNodesField

    field :scores, [Types::ScoreType], null: false
    def scores
      Score.all
    end

    field :score, Types::ScoreType, null: false do
      argument :id, Int, required: false
    end
    def score(id:)
      Score.find(id)
    end
  end
end
```

これでGraphQL使えるようになったと思うので、コンソールで動き確かめてみます。

```
$ docker-compose rum --rm web bundle exec rails c
```
でコンソール起動
```
> Score.create(title: "title")
```
でデータ作成。
公式では`GraphQL::Schema`を継承したクラスを作成していますが、AppSchemaでも動作確認できました。
```
> AppSchema.execute("{scores{id title}}").to_hash
    Score Load (17.1ms)  SELECT `scores`.* FROM `scores`
    => {"data"=>{"scores"=>[{"id"=>"1", "title"=>"title"}]}}
```
ちゃんと取得できてそうです！
uuidにしたいけどmysqlじゃ難しいっぽいな…

とりあえずここまで。次回はフロントで表示するところまでやろうかと思います！

# 補足
graphqlの動作をローカルのサーバー上で確認できる`graphiql`というgemがあるらしいのですが、`ActionDispatch::Request::Session::DisabledSessionError`とエラーが出て表示できず。
Rails７系からAPIモードにするとセッション無効になるとかで、良い解決方法は無さそうだったので今回はこのgemの使用は見送りました。コンソールでも確認できたし別にいいかな。apollo使えればそれで同じこともできるはずなので。

# 参考にさせていただいたサイト・記事
- [graphql-ruby公式](https://graphql-ruby.org/getting_started)
- [【Rails】graphql-rubyでAPIを作成](https://qiita.com/k-penguin-sato/items/07fef2f26fd6339e0e69)
- [Rails + GraphQLでAPI作成](https://zenn.dev/slowhand/articles/4fe99377185100)
- [Rails APIモードで始めるGraphQL](https://qiita.com/dkawabata/items/4fd965ee6d7295386a8b)
- [初めてのGraphQL with Rails](https://qiita.com/sazumy/items/58106174392516da5f1d)