RubyonRailsGraphQLAPIをセットアップする方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 FreePressを選択して寄付を受け取りました。

序章

GraphQL は、API用の強く型付けされたクエリ言語であり、既存のデータを使用してこれらのクエリを実行するためのサーバー側ランタイムです。 GraphQLを使用すると、クライアントはクエリで必要な正確なデータを指定できるようになり、1回のリクエストでサーバーから複数のリソースをフェッチできます。 これにより、複数のAPI呼び出しが不要になります。 GraphQLは言語とデータベースに依存しないため、選択したデータベースとともに、ほぼすべてのプログラミング言語で実装できます。

このチュートリアルでは、メモを取るためのGraphQLを利用したRuby onRailsAPIを構築します。 終了すると、GraphQLを使用してAPIからメモを作成および表示できるようになります。

このチュートリアルのコードを確認したい場合は、 DigitalOcean CommunityGitHubでこのチュートリアルのコンパニオンリポジトリを確認してください。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • 開発マシンにインストールされているRubyプログラミング言語とRubyonRailsフレームワーク。 このチュートリアルは、Rubyのバージョン2.6.3およびRailsのバージョン6.0.2.1でテストされているため、インストールプロセス中にこれらのバージョンを指定してください。 次のチュートリアルのいずれかに従って、RubyとRailsをインストールします。 Ubuntu18.04でrbenvを使用してRubyonRailsをインストールする方法CentOS7でrbenvを使用してRubyonRailsをインストールする方法。 macOSでrbenvを使用してRubyonRailsをインストールする方法。
  • PostgreSQLがインストールされています。 このチュートリアルに従うには、PostgreSQLバージョン11.2を使用します。 次のいずれかのチュートリアルのステップ1と2に従って、PostgreSQLをインストールします。 Ubuntu18.04のRubyonRailsアプリケーションでPostgreSQLを使用する方法macOSのRubyonRailsアプリケーションでPostgreSQLを使用する方法。 Linuxの別のディストリビューションまたは別のオペレーティングシステムでこのアプリケーションを開発するには、PostgreSQLの公式ダウンロードページにアクセスしてください。 PostgreSQLの使用方法の詳細については、「PostgreSQLをインストールして使用する方法」を参照してください。

ステップ1—新しいRailsAPIアプリケーションをセットアップする

このステップでは、新しいRails APIアプリケーションをセットアップし、それをPostgreSQLデータベースに接続します。 これは、メモを取るAPIの基盤として機能します。

Railsは、開発者が最新のWebアプリケーションをより速く構築できるようにするコマンドを提供します。 これらのコマンドは、新しいRailsアプリケーションの作成から、アプリ開発に必要なファイルの生成まで、さまざまなアクションを実行できます。 これらのコマンドの完全なリストとその機能については、ターミナルウィンドウで次のコマンドを実行してください。

rails -h

このコマンドは、アプリケーションのパラメーターを設定するために使用できるオプションの広範なリストを生成します。 リストされているコマンドの1つは、newコマンドです。このコマンドは、APP_PATHを受け入れ、指定されたパスに新しいRailsアプリケーションを作成します。

newジェネレーターを使用して新しいRailsアプリケーションを作成します。 ターミナルウィンドウで次のコマンドを実行します。

rails new rails_graphql -d=postgresql -T --api

これにより、rails_graphqlという名前のディレクトリに新しいRailsアプリケーションが作成され、必要な依存関係がインストールされます。 newコマンドに関連するフラグを調べてみましょう。

  • -dフラグは、指定されたデータベースでアプリケーションを事前構成します。
  • -Tフラグは、このチュートリアルではテストを作成しないため、Railsにテストファイルを生成しないように指示します。 Railsが提供するもの以外の別のテストフレームワークを使用する場合にも、このフラグを使用できます。
  • --apiフラグは、Railsを使用してAPIを構築するために必要なファイルのみを使用してRailsアプリケーションを構成します。 ブラウザアプリケーションに必要な設定の構成をスキップします。

コマンドの実行が完了したら、アプリケーションのルートディレクトリである新しく作成されたrails_graphqlディレクトリに切り替えます。

cd rails_graphql

これで、新しいRails APIアプリケーションが正常にセットアップされたので、アプリを実行する前に、それをデータベースに接続する必要があります。 Railsは、config/database.ymlにあるdatabase.ymlファイルを提供します。このファイルには、さまざまな開発環境のさまざまなデータベースにアプリを接続するための構成が含まれています。 Railsは、アプリの名前にアンダースコア(_)の後に環境名を追加することにより、さまざまな開発環境のデータベース名を指定します。 環境データベース名はいつでも好きな名前に変更できます。

注: config/database.ymlを変更して、Railsがデータベースの作成に使用するPostgreSQLの役割を選択できます。 パスワードで保護されたロールを作成した場合は、 Ubuntu18.04またはHowToでRubyonRailsアプリケーションでPostgreSQLを使用する方法のステップ4の手順に従ってください。 macOS上のRubyonRailsアプリケーションでPostgreSQLを使用して、役割を構成します。


Railsには、データベースを作成および操作するためのコマンドが含まれています。 データベースのクレデンシャルを設定したら、ターミナルウィンドウで次のコマンドを実行してデータベースを作成します。

rails db:create

db:createコマンドは、config/database.ymlファイルで提供される情報に基づいて、developmentおよびtestデータベースを作成します。 コマンドを実行すると、次の出力が得られます。

OutputCreated database 'rails_graphql_development'
Created database 'rails_graphql_test'

アプリケーションがデータベースに正常に接続されたら、アプリケーションをテストして動作することを確認できます。 ローカルで作業している場合は、次のコマンドを使用してサーバーを起動します。

bundle exec rails server

開発サーバーで作業している場合は、サーバーがバインドするIPアドレスを指定してアプリケーションを起動できます。

bundle exec rails server --binding=your_server_ip

:サーバーはポート3000でリッスンします。 開発サーバーで作業している場合は、ファイアウォールでポート3000を開いて、接続を許可していることを確認してください。


rails serverコマンドは、Railsとともに配布されるRuby用のWebサーバーであるPumaを起動します。 --binding=your_server_ipコマンドは、サーバーを指定したIPにバインドします。

このコマンドを実行すると、コマンドプロンプトは次の出力に置き換えられます。

Output=> Booting Puma
=> Rails 6.0.2.1 application starting in development
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.1 (ruby 2.6.3-p62), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop

アプリケーションを実行するには、ブラウザでlocalhost:3000またはhttp://your_server_ip:3000に移動します。 Railsのデフォルトのウェルカムページが表示されます。

ウェルカムページは、Railsアプリケーションが適切に設定されていることを意味します。

サーバーを停止するには、サーバーが実行されているターミナルウィンドウでCTRL+Cを押します。

これで、メモを取るAPI用のRailsAPIアプリケーションが正常にセットアップされました。 次のステップでは、GraphQLクエリを受信して実行するようにRailsAPIアプリケーションを設定します。

ステップ2—Rails用のGraphQLのセットアップ

このステップでは、GraphQLで動作するようにRailsAPIアプリケーションを構成します。 RailsでのGraphQL開発に必要なgemをインストールしてセットアップします。

前述のように、GraphQLは言語に依存せず、多くのプログラミング言語で実装されています。 graphql-ruby gemは、GraphQLのRuby実装です。 GraphQLは、GraphQLクエリを実行するためのGraphiQLと呼ばれるインタラクティブなブラウザー内IDEも提供します。 grafiql-rails gemは、開発環境にGraphiQLを追加するのに役立ちます。

これらの依存関係をインストールするには、nanoまたはお気に入りのテキストエディタを使用して、プロジェクトのGemfileを開いて編集します。

nano Gemfile

graphqlおよびgraphiql-railsgemをGemfileに追加します。 graphiql gemはどこにでも追加できますが、graphiql-railsgemは開発の依存関係の下に追加する必要があります。

〜/ rails_graphql / Gemfile

...
group :development do
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  gem 'graphiql-rails'
end

gem 'graphql', '1.9.18'
...

gemの追加が完了したら、ファイルを保存して閉じます。

ターミナルウィンドウで、次のコマンドを使用してgemをインストールします。

bundle install

出力は、gemがインストールされていることを示しています。

graphql gemは、さまざまなファイルを作成するためのジェネレーターを提供します。 使用可能なジェネレーターを表示するには、ターミナルウィンドウで次のコマンドを実行します。

rails generate

graphql:のプレフィックスが付いたジェネレーターは、graphqlジェムに関連付けられているジェネレーターです。

graphql:installコマンドを使用して、graphql-rubyボイラープレートコードをアプリケーションに追加し、開発環境にGraphiQLをマウントします。 ボイラープレートコードには、graphql-rubygemがRailsで動作するために必要なすべてのファイルとディレクトリが含まれます。

ターミナルウィンドウで、次のコマンドを実行します。

rails g graphql:install

このコマンドは、app/controllers/graphql_controller.rbにあるgraphql_controller.rbファイルやapp/graphqlにあるgraphqlディレクトリを含むいくつかのファイルを生成します。 。 また、config/routes.rbにあるルートファイルに/graphql HTTPPOSTルートを追加します。 このルートは、GraphQLサーバーへのすべてのクエリを処理するapp/controllers/graphql_controller.rb#executeメソッドにマップされます。

GraphQLエンドポイントをテストする前に、GraphiQLエンジンをroutesファイルにマウントして、GraphiQLブラウザー内IDEにアクセスできるようにする必要があります。 これを行うには、config/routes.rbにあるルートファイルを開きます。

nano ~/rails_graphql/config/routes.rb

次のコードをファイルに追加して、開発環境にGraphiQLエンジンをマウントします。

〜/ rails_graphql / config / routers.rb

Rails.application.routes.draw do
  if Rails.env.development?
    mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "graphql#execute"
  end
  post "/graphql", to: "graphql#execute"
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

これにより、GraphiQLエンジンが/graphiqlパスにマウントされ、すべてのクエリがgraphql#executeメソッドに転送されます。

これは--apiフラグを使用して作成されたAPIアプリケーションであるため、ブラウザーでページをレンダリングすることは想定されていません。 GraphiQLエディターをブラウザーに表示するには、アプリケーションの構成にいくつかの小さな変更を加える必要があります。

まず、config/application.rbにあるapplication.rbファイルを開きます。

nano ~/rails_graphql/config/application.rb

次に、require "sprockets/railtie"行のコメントを解除します。

〜/ rails_graphql / config / application.rb

require_relative 'boot'

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

...

行のコメントを解除した後、ファイルを保存して閉じます。

次に、app/assetsconfigディレクトリを作成します。

mkdir -p app/assets/config

次に、新しく作成したconfigディレクトリにmanifest.jsファイルを作成します。 manifest.jsファイルは、コンパイルしてブラウザーで使用できるようにする追加のアセットを指定します。

nano app/assets/config/manifest.js

Railsにgraphiql/rails/application.cssおよびgraphiql/rails/application.jsファイルをプリコンパイルするように指示するファイルに次のコードを追加して、Railsがそれらをブラウザーに提供できるようにします。

〜/ rails_graphql / app / Assets / config /manifest.js

//= link graphiql/rails/application.css
//= link graphiql/rails/application.js

ファイルを保存して閉じます。

これで、GraphQLエンドポイントをテストできます。 開発サーバーを再起動し、ブラウザーでlocalhost:3000/graphiqlまたはhttp://your_server_ip:3000/graphiqlに移動します。 GraphiQLクエリエディターがブラウザーに表示されます。

GraphiQL IDEの左側はGraphQLクエリを受け入れ、右側は実行クエリの結果を表示します。 GraphiQLクエリエディターには、GraphQLスキーマを利用した構文ハイライトと先行入力ヒントもあります。 一緒に、これらはあなたが有効なクエリを作るのを助けます。

Hello Worldの例を試すには、エディターの左側のペインでデフォルトのテキストをクリアし、次のクエリを入力します。

query {
    testField
}

次の図に示すように、ヘッダーの再生アイコンボタンをクリックすると、画面に正常な応答が表示されます。

これで、Rails APIアプリケーションがGraphQLで動作するように正常にセットアップされ、GraphQLエンドポイントが動作することを確認するためにテストされました。 次のステップでは、アプリケーションのGraphQLタイプを作成します。

ステップ3—アプリケーションのタイプを作成する

GraphQLは、クエリの検証と応答をタイプとスキーマに依存しています。 このステップでは、メモを取るAPIに必要なメモモデルとGraphQLタイプを作成します。

GraphQLタイプは、fieldsargumentsで構成され、そのタイプを操作するGraphQLクエリに表示されるフィールドと引数を定義します。 これらのタイプはGraphQLスキーマを構成します。 GraphQLは、次のタイプを定義します。

  • クエリタイプとミューテーションタイプ:これらは、すべてのGraphQLクエリのエントリポイントを定義する特別なタイプです。 すべてのGraphQLサービスにはqueryタイプがあり、mutationタイプがある場合とない場合があります。
  • オブジェクトタイプ:これらはGraphQLスキーマの基本的なコンポーネントです。 これらは、GraphQLサービスからフェッチできるオブジェクトと、各オブジェクトが保持するフィールドを表します。
  • スカラータイプ:これらは、GraphQLに標準で付属しているデフォルトのタイプです。 それらには、IntFloatStringBoolean、およびIDが含まれます。
  • 列挙型:これらは、許可された値の特定のセットを定義する型です。
  • 入力タイプ:これらはオブジェクトタイプに似ていますが、唯一の違いは、クエリに引数として渡すことができるオブジェクトを定義することです。

UnionListNon-NullInterfaceなどの他のタイプがあります。 利用可能なGraphQLタイプのリストは、公式のGraphQLドキュメントにあります。

このアプリケーションでは、NoteモデルとNoteオブジェクトおよび入力タイプを作成します。 Noteモデルは、メモを格納するデータベーステーブルを表し、Noteオブジェクトと入力タイプは、Noteオブジェクトに存在するフィールドと引数を定義します。

まず、Railsが提供するgenerate modelサブコマンドを使用してNoteモデルを作成し、モデルの名前とその列およびデータ型を指定します。 ターミナルウィンドウで次のコマンドを実行します。

rails generate model note title:string:index body:text

このコマンドは、タイプstringtitleとタイプtextbodyの2つのフィールドを持つNoteモデルを作成します。 このコマンドは、title列にデータベースindexも追加します。 次の2つのファイルが生成されます。

  • app/models/note.rbにあるnote.rbファイル。 このファイルには、モデルに関連するすべてのロジックが含まれます。
  • db/migrate/20200617173228_create_notes.rbにある20200617173228_create_notes.rbファイル(ファイルの先頭の番号は、コマンドを実行した日付によって異なります)。 これは、データベースに対応するnotesテーブルを作成するための命令を保持する移行ファイルです。

移行ファイルの命令を実行するには、移行ファイルの命令を実行するdb:migrateサブコマンドを使用します。 ターミナルウィンドウで次のコマンドを実行します。

rails db:migrate

コマンドが正常に実行されると、次のような出力が表示されます。

Output== 20200617173228 CreateNotes: migrating ======================================
-- create_table(:notes)
   -> 0.0134s
-- add_index(:notes, :title)
   -> 0.0073s
== 20200617173228 CreateNotes: migrated (0.0208s) =============================

ノートモデルを配置したら、次にNoteTypeを作成します。 有効なノートオブジェクトには、idtitle、およびtextが必要です。 ターミナルウィンドウで次のコマンドを実行して、NoteTypeを作成します。

rails generate graphql:object Note id:ID! title:String! body:String!

このコマンドは、Noteという3つのフィールドを持つGraphQLオブジェクトタイプを作成するようにRailsに指示します。 X163X] フィールド、それぞれStringタイプ。 フィールドタイプに追加された感嘆符(!)は、フィールドがnull不可であることを示します。つまり、フィールドがnull値を返すことはありません。 null不可能なフィールドは、GraphQLオブジェクトが照会されるたびにどのフィールドが存在しなければならないかを保証する検証の形式として機能するため、重要です。

上記のコマンドを実行すると、app/graphql/types/note_type.rbnote_type.rbファイルが作成されます。このファイルには、3つのnull許容フィールドを含むTypes::NoteTypeクラスが含まれています。

最後に、NoteInputタイプを作成して、メモの作成に必要な引数を定義します。 app/graphql/typesの下にinputディレクトリを作成することから始めます。 入力ディレクトリには、入力タイプが格納されます。

mkdir ~/rails_graphql/app/graphql/types/input

注:入力ディレクトリに入力タイプを作成する必要はありません。 これは単なる一般的な慣習です。 すべてのタイプをtypesディレクトリに保持し、アクセスするたびにInputモジュールの下にクラスをネストしないようにすることができます。


~/rails_graphql/app/graphql/types/inputディレクトリに、note_input_type.rbファイルを作成します。

nano ~/rails_graphql/app/graphql/types/input/note_input_type.rb

次のコードをファイルに追加して、Inputタイプのフィールドを定義します。

〜/ rails_graphql / app /graphql/types/input/note_input_type.rb

module Types
  module Input
    class NoteInputType < Types::BaseInputObject
      argument :title, String, required: true
      argument :body, String, required: true
    end
  end
end

note_input_type.rbファイルに、Types::BaseInputObjectクラスを継承し、2つの必須引数を受け入れるTypes::Input::NoteInputTypeクラスを追加しました。 titlebody、どちらも文字列タイプ。

メモを取るアプリ用にモデルと2つのGraphQLタイプを作成しました。 次のステップでは、既存のメモを取得するためのクエリを作成します。

ステップ4—アプリケーションのクエリを作成する

GraphQLを利用したAPIが徐々に統合されています。 このステップでは、2つのクエリを作成します。 1つはidで単一のノートをフェッチし、もう1つはすべてのノートをフェッチします。 GraphQL queryタイプは、データのフェッチを処理し、RESTのGETリクエストに例えることができます。

まず、すべてのメモを取得するクエリを作成します。 まず、すべてのクエリを格納するqueriesディレクトリを作成します。

mkdir ~/rails_graphql/app/graphql/queries

app/graphql/queriesディレクトリに、他のすべてのクエリクラスが継承するbase_query.rbファイルを作成します。

nano ~/rails_graphql/app/graphql/queries/base_query.rb

次のコードをbase_query.rbファイルに追加して、他のクエリクラスが継承するBaseQueryクラスを作成します。

〜/ rails_graphql / app /graphql/queries/base_query.rb

module Queries
  class BaseQuery < GraphQL::Schema::Resolver
  end
end

base_query.rbファイルに、GraphQL::Schema::Resolverクラスを継承するQueries::BaseQueryクラスを追加しました。 GraphQL::Schema::Resolverクラスは、fieldに属するロジックを保持できるコンテナーです。 resolver:キーワードでfieldにアタッチできます。

Queries::BaseQueryクラスには、複数のクエリクラスで再利用する予定のコードを含めることもできます。

次に、queriesディレクトリにfetch_notes.rbファイルを作成します。 このファイルは、既存のすべてのメモをフェッチするためのロジックを保持し、クエリタイプファイルのfieldに添付されます。

nano ~/rails_graphql/app/graphql/queries/fetch_notes.rb

次のコードをファイルに追加して、戻りオブジェクトタイプを定義し、要求されたメモを解決します。

〜/ rails_graphql / app /graphql/queries/fetch_notes.rb

module Queries
  class FetchNotes < Queries::BaseQuery

    type [Types::NoteType], null: false

    def resolve
      Note.all.order(created_at: :desc)
    end
  end
end

fetch_notes.rbファイルで、以前に作成したQueries::BaseQueryを継承するQueries::FetchNotesクラスを作成しました。 このクラスには、このクエリによって返されるデータが既に作成されたNoteTypeの配列である必要があることを宣言するreturntype宣言があります。

Queries::FetchNotesには、resolveメソッドも含まれています。このメソッドは、作成された日付の降順で並べ替えられた既存のすべてのメモの配列を返します。

FetchNotesクエリはメモのリクエストを受信して返す準備ができていますが、GraphQLはまだその存在を認識していません。これを修正するには、app/graphql/types/query_type.rbにあるGraphQLクエリタイプファイルを開きます。

nano ~/rails_graphql/app/graphql/types/query_type.rb

query_type.rbファイルは、すべてのGraphQLqueryタイプのエントリポイントです。 クエリフィールドとそれぞれのリゾルバメソッドを保持します。 ファイル内のサンプルコードを次のように置き換えます。

〜/ rails_graphql / app /graphql/types/query_type.rb

module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :fetch_notes, resolver: Queries::FetchNotes
  end
end

query_type.rbファイルで、fetch_notesフィールドを追加し、resolver:を使用してQueries::FetchNotesクラスにアタッチしました。 このようにして、fetch_notesクエリが呼び出されるたびに、Queries::FetchNotesクラスのresolveメソッドのロジックが実行されます。

クエリをテストするには、フェッチするデータが必要ですが、現在データベースにメモがありません。 データベースにシードデータを追加することで、これを修正できます。 db/seeds.rbにあるseeds.rbファイルを開きます。

nano ~/rails_graphql/db/seeds.rb

次のコードをファイルに追加して、5つのメモを作成します。

〜/ rails_graphql / db / seeds.rb

5.times do |i|
  Note.create(title: "Note #{i + 1}", body: 'Lorem ipsum saves lives')
end

コードを追加したら、ファイルを保存して閉じます。

別のターミナルウィンドウでプロジェクトのルートディレクトリを開き、次のコマンドを実行してseed.rbファイルのコードを実行します。

rails db:seed

これにより、データベースに5つのメモが作成されます。

データベースにデータがあり、開発サーバーが実行されている状態で、ブラウザーでlocalhost:3000/graphiqlまたはhttp://your_server_ip:3000/graphiqlに移動して、GraphiQLIDEを開きます。 エディタの左側に、次のクエリを入力します。

query {
  fetchNotes {
    id
    title
    body
  }
}

このGraphQLクエリは、query操作を宣言し、クエリ要求を行うことを示します。 クエリ操作で、APIで宣言されたfetch_notesクエリフィールドと一致するfetchNotesフィールドを呼び出し、応答で返されるメモのフィールドを含めました。

ヘッダーの再生アイコンボタンをクリックします。 出力ペインに次のような応答が表示されます。

{
  "data": {
    "fetchNotes": [
      {
        "id": "5",
        "title": "Note 5",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "4",
        "title": "Note 4",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "3",
        "title": "Note 3",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "2",
        "title": "Note 2",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "1",
        "title": "Note 1",
        "body": "Lorem ipsum saves lives"
      }
    ]
  }
}

応答には、左側のクエリで宣言されたフィールドに一致する5つのメモの配列が含まれています。 エディターの左側にあるクエリの一部のフィールドを削除してクエリを再実行すると、要求したフィールドのみを含む応答が返されます。 それがGraphQLの力です。

次に、idでメモを取得する別のクエリを作成します。 このクエリはfetch_notesクエリに似ていますが、id引数を受け入れる点が異なります。 先に進み、querysディレクトリにfetch_note.rbファイルを作成します。

nano ~/rails_graphql/app/graphql/queries/fetch_note.rb

次のコードをファイルに追加して、提供されたidを含むメモを見つけて返します。

〜/ rails_graphql / app /graphql/queries/fetch_note.rb

module Queries
  class FetchNote < Queries::BaseQuery
    type Types::NoteType, null: false
    argument :id, ID, required: true

    def resolve(id:)
      Note.find(id)
    rescue ActiveRecord::RecordNotFound => _e
      GraphQL::ExecutionError.new('Note does not exist.')
    rescue ActiveRecord::RecordInvalid => e
      GraphQL::ExecutionError.new("Invalid attributes for #{e.record.class}:"\
        " #{e.record.errors.full_messages.join(', ')}")
    end
  end
end

これは、Queries::BaseQueryクラスから継承するQueries::FetchNoteクラスを定義します。 このクラスは、NoteTypeでなければならない単一のアイテムを返すだけでなく、IDタイプのid引数も受け入れます。 resolveメソッドは、提供されたid引数を受け取り、提供されたidを含むメモを見つけて返します。 メモが存在しないかエラーが発生した場合、メモはレスキューされ、GraphQL::ExecutionErrorとして返されます。

次に、Queries::FetchNoteクラスをクエリタイプファイルのクエリフィールドにアタッチします。 エディタでquery_type.rbファイルを開きます。

nano ~/rails_graphql/app/graphql/types/query_type.rb

fetch_notesのリゾルバーを定義するファイルに次のコードを追加します。

〜/ rails_graphql / app /graphql/types/query_type.rb

module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :fetch_notes, resolver: Queries::FetchNotes
    field :fetch_note, resolver: Queries::FetchNote
  end
end

新しいクエリをテストするには、サーバーが実行されていることを確認し、ブラウザーでlocalhost:3000/graphiqlまたはhttp://your_server_ip:3000/graphiqlに移動してGraphiQLIDEを開きます。 エディタの左側に、次のクエリを入力します。

query {
  fetchNote(id: 1) {
    id
    title
    body
  }
}

このクエリ操作は、fetch_noteクエリフィールドに対応するfetchNoteフィールドを要求し、id引数が渡されます。 これは、応答で3つのフィールドを返すことを指定します。

ヘッダーの再生アイコンボタンをクリックしてクエリを実行します。 出力ペインに次のような応答が表示されます。

{
  "data": {
    "fetchNote": {
      "id": "1",
      "title": "Note 1",
      "body": "Lorem ipsum saves lives"
    }
  }
}

応答には、要求されたidと、要求内のフィールドと一致するフィールドに一致する単一のメモが含まれています。

このステップでは、APIからメモをフェッチするためのGraphQLクエリを作成しました。 次に、メモを作成するためのミューテーションを記述します。

ステップ5—メモを変更するためのGraphQLミューテーションの作成

クエリに加えて、GraphQLは、サーバー側のデータを変更する操作のmutationタイプも定義します。 RESTがリソースの作成、更新、削除のためのPOSTPUTPATCH、およびDELETEリクエストを提供するように、GraphQLのmutationタイプはサーバー側で書き込みを発生させる操作の規則。 このステップでは、新しいノートを追加するためのミューテーションを作成します。

graphQL-rubyには、ミューテーションを書き込むための2つのクラスが含まれています。 彼らです:

  • GraphQL :: Schema :: Mutation :これはミューテーションを記述するための一般的な基本クラスです。 ミューテーションでinput引数を必要としない場合は、このクラスを使用する必要があります。
  • GraphQL :: Schema :: RelayClassicMutation :これはいくつかの規則がある基本クラスです。 常に応答に挿入されるclientMutationIdと呼ばれる引数、およびinputと呼ばれる1つの引数を受け入れるミューテーション。 このクラスは、install generatorを使用してボイラープレートGraphQLファイルをプロジェクトに追加するときにデフォルトで使用されます。

app/graphql/mutationsにあるmutationsディレクトリにadd_note.rbファイルを作成します。

nano ~/rails_graphql/app/graphql/mutations/add_note.rb

次のコードをファイルに追加して、新しいメモを追加するためのミューテーションを定義します。

〜/ rails_graphql / app /graphql/mutations/add_note.rb

module Mutations
  class AddNote < Mutations::BaseMutation
    argument :params, Types::Input::NoteInputType, required: true

    field :note, Types::NoteType, null: false

    def resolve(params:)
      note_params = Hash params

      begin
        note = Note.create!(note_params)

        { note: note }
      rescue ActiveRecord::RecordInvalid => e
        GraphQL::ExecutionError.new("Invalid attributes for #{e.record.class}:"\
          " #{e.record.errors.full_messages.join(', ')}")
      end
    end
  end
end

これは、Mutations::BaseMutationクラスを継承するMutations::AddNoteクラスを定義します。これは、GraphQL-Rubygemのインストール中にinstall generatorを実行したときに作成されるクラスの1つです。 Mutations::AddNoteクラスは、paramsという名前とステップ3で作成したNoteInputTypeのタイプのargumentを受け取ります。 また、noteと呼ばれるfieldを返します。これは、null以外のNoteTypeタイプである必要があります。

クラスのresolveメソッドは、paramsを受け取り、それをハッシュに変換します。このハッシュを使用して、新しいメモを含む新しいハッシュを作成して返します。 メモの作成中にエラーが発生した場合、エラーはレスキューされ、GraphQL::ExecutionErrorとして返されます。

注:ミューテーションのresolveメソッドは、シンボルがfield名と一致するハッシュを返す必要があります。


クエリと同様に、Mutations::AddNoteミューテーションは、mutation:キーワードを使用してミューテーションフィールドにアタッチする必要があります。

エディタでapp/graphql/types/mutation_type.rbにあるミューテーションタイプファイルを開きます。

nano ~/rails_graphql/app/graphql/types/mutation_type.rb

ファイル内のコードを次のコードに置き換えます。これにより、add_noteのフィールドが対応するミューテーションクラスに追加されます。

〜/ rails_graphql / app /graphql/types/mutation_type.rb

module Types
  class MutationType < Types::BaseObject
    field :add_note, mutation: Mutations::AddNote
  end
end

このコードでは、ミューテーションタイプファイルにadd_noteフィールドを追加し、mutation:キーワードを使用してMutations::AddNoteクラスにアタッチしました。 add_noteミューテーションが呼び出されると、Mutations::AddNoteクラスのresolveメソッドのコードが実行されます。

新しいミューテーションをテストするには、ブラウザーでlocalhost:3000/graphiqlまたはhttp://your_server_ip:3000/graphiqlに移動して、GraphiQLIDEを開きます。 エディタの左側に、次のクエリを入力します。

mutation {
  addNote(input: { params: { title: "GraphQL notes", body: "A long body of text about GraphQL"  }}) {
    note {
      id
      title
      body
    }
  }
}

これは、単一のinput引数を受け入れるaddNoteフィールドを使用したミューテーション操作を宣言します。この引数は、NoteInputTypeと一致するキーを持つparamオブジェクトを受け入れます。 ミューテーション操作には、Mutations::AddNoteクラスによって返されるnoteフィールドと一致するnoteフィールドも含まれます。

GraphiQLでミューテーションを実行すると、出力ペインに次の結果が表示されます。

{
  "data": {
    "addNote": {
      "note": {
        "id": "6",
        "title": "GraphQL notes",
        "body": "A long body of text about GraphQL"
      }
    }
  }
}

返される応答は、ミューテーション要求で要求されたフィールドを持つ新しく作成されたメモです。

add_noteミューテーションが機能するようになったので、APIはGraphQLクエリとミューテーションを使用してメモをフェッチおよび作成できます。

結論

このチュートリアルでは、データベースとしてPostgreSQLを使用し、APIクエリ言語としてGraphQLを使用して、RubyonRailsでメモを取るAPIアプリケーションを作成しました。 GraphQLの詳細については、公式ウェブサイトをご覧ください。 GraphQL-Ruby gem Webサイトには、RailsでGraphQLを操作するのに役立つガイドもいくつか含まれています。