🚶

GraphQL-Ruby でCRUD処理(前編)

2023/04/22に公開約5,500字

はじめに

GraphQL-Ruby を使用して CRUD 処理を実装していきます。

今回は、Rails アプリケーションに GraphQL を導入し、CRUD 処理の Read に相当する query を実装していきます。

環境

  • Ruby 2.7.5
  • Rails 6.1.7
  • GraphQL-Ruby 1.11.6

Rails プロジェクトの作成

まずは Rails プロジェクトの作成を行います。以下のコマンドを実行してください。

$ rails new micropost-app --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-storage --skip-action-cable --skip-javascript --skip-system-test --skip-webpack-install

作成したプロジェクトのディレクトリに移動し、データベースを作成します。

$ cd micropost-app
$ bundle exec rails db:create

ローカルサーバーを起動して、http://localhost:3000/ にアクセスし、お馴染みの画面が表示されることを確認します。

$ bundle exec rails server

GraphQL-Ruby のインストール

次に、Rails プロジェクトにGraphQL-Rubyをインストールしていきます。
Gemfile に以下の行を追加します。

gem 'graphql', '1.11.6'

bundle install コマンドを実行して Gem をインストールします。

$ bundle install

インストールが完了したら、GraphQL を利用するためのファイルを自動生成するためのコマンドを実行します。

$ bundle exec rails generate graphql:install

これで GraphQL API を作成するための準備は整いました。

Micropost モデルの作成

今回は Micropost の CRUD 処理を実装していきます。
Micropost モデルについては Rails チュートリアルのものを参考にしています。

参考: 第 2 章 Toy アプリケーション - Rails チュートリアル

モデルの作成と DB マイグレーションをしていきます。

$ bundle exec rails generate model Micropost content:text
$ bundle exec rails db:migrate

サンプルデータを挿入しておきます。

$ rails console
rb(main):001:0> Micropost.create(content: "サンプルコンテンツ")
irb(main):002:0> Micropost.create(content: "サンプルコンテンツ2")

特定のマイクロポストを取得する Query の実装

次に、特定のマイクロポストを取得する Query を実装します。
Query を実行するためには以下の手順が必要になります。

  1. マイクロポストモデルの GraphQL タイプの作成
  2. ベースの resolver の作成
  3. 特定マイクロポストを取得する Query resolver の作成
  4. Query resolver の公開

1. マイクロポストモデルの GraphQL タイプの作成

マイクロポストモデルの GraphQL タイプを作成します。これは、GraphQL スキーマ内で使用するオブジェクトタイプになり、レスポンスの型となります。
以下のコマンドでファイルを自動生成します。

$ rails g graphql:object MicropostType id:ID! content:String!

以下のファイルが生成されます。

app/graphql/types/micropost_type.rb
module Types
  class MicropostType < Types::BaseObject
    field :id, ID, null: false
    field :content, String, null: false
  end
end

各フィールドの名前、型、null 許容性を定義しています。
今回は、idcontent のフィールドを定義しており、それぞれ ID 型と String 型を指定しています。また、両方とも null を許容していません。

利用できる型については Schemas and Types | GraphQL をご参考ください。

2. ベースの resolver の作成

resolver を作成するにあたって、ベースとなる resolver を作成します。
app/graphql/resolvers/base_resolver.rb を新規で作成します。

app/graphql/resolvers/base_resolver.rb
module Resolvers
  class BaseResolver < GraphQL::Schema::Resolver
    argument_class Types::BaseArgument
  end
end

3. 特定マイクロポストを取得する Query resolver の作成

特定のマイクロポストを取得するための Query resolver を作成していきます。
app/graphql/resolvers/micropost_resolver.rb を新規で作成します。

app/graphql/resolvers/micropost_resolver.rb
module Resolvers
  class MicropostResolver < Resolvers::BaseResolver
    argument :id, ID, required: true

    type Types::MicropostType, null: true

    def resolve(id:)
      Micropost.find_by(id: id)
    end
  end
end

この resolver では、type に指定されている 手順 1 で定義した MicropostType のオブジェクトを返します。
引数としては、id を受け取り、id を利用してマイクロポストを取得します。これをレスポンスします。

4. Query resolver の公開

手順 3 で作成した Query resolver を利用できるようにするよう公開します。
app/graphql/types/query_type.rb を修正します。

app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    field :micropost, resolver: Resolvers::MicropostResolver
  end
end

これで Query に micropost を指定すると、手順 3 で実装した Resolvers::MicropostResolver が処理されます。

これで、特定のマイクロポストを取得する Query を実行する準備が整いました。

実行する

http://localhost:3000/graphiql で実行結果を確認できます。
id が 1 のマイクロポストを実行する Query を指定し実行します。

query {
  micropost(id: 1) {
    id
    content
  }
}

id が 1 のマイクロポストがレスポンスされるはずです。

{
	"data": {
		"micropost": {
			"id": "1",
			"content": "サンプルコンテンツ"
		}
	}
}

全てのマイクロポストを取得する Query の実装

次に、全てのマイクロポストを取得する Query を実装します。
Query を実行するためには以下の手順が必要になります。

  1. 全てのマイクロポストを取得する Query resolver の作成
  2. Query resolver の公開

1. 全てのマイクロポストを取得する Query resolver の作成

全てのマイクロポストを取得するための Query resolver を作成していきます。
app/graphql/resolvers/microposts_resolver.rb を新規で作成します。

app/graphql/resolvers/microposts_resolver.rb
module Resolvers
  class MicropostsResolver < Resolvers::BaseResolver
    type [Types::MicropostType], null: true

    def resolve
      Micropost.all
    end
  end
end

この resolver では全てのマイクロポストを取得し、レスポンスします。

2. Query resolver の公開

手順 1 で作成した Query resolver を利用できるようにします。
app/graphql/types/query_type.rb を修正します。

app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
    field :micropost, resolver: Resolvers::MicropostResolver
+   field :microposts, resolver: Resolvers::MicropostsResolver
  end
end

これで Query に microposts を指定すると、手順 1 で実装した Resolvers::MicropostsResolver を使用して処理が実行されます。

実行してみる

http://localhost:3000/graphiql で以下の Query を実行します。

query {
  microposts {
    id
    content
  }
}

全てのマイクロポストがレスポンスされるはずです。

{
	"data": {
		"microposts": [
			{
				"id": "1",
				"content": "サンプルコンテンツ"
			},
			{
				"id": "2",
				"content": "サンプルコンテンツ2"
			}
		]
	}
}

次回は、 CRUD 処理の Create, Update, Delete に相当する mutation を実装していきます。

GraphQL-Ruby で CRUD 処理(後編)

Discussion

ログインするとコメントできます