RubyonRailsGraphQLAPIをセットアップする方法
著者は、 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-rails
gemをGemfileに追加します。 graphiql
gemはどこにでも追加できますが、graphiql-rails
gemは開発の依存関係の下に追加する必要があります。
〜/ 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-ruby
gemが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/assets
にconfig
ディレクトリを作成します。
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タイプは、fields
とarguments
で構成され、そのタイプを操作するGraphQLクエリに表示されるフィールドと引数を定義します。 これらのタイプはGraphQLスキーマを構成します。 GraphQLは、次のタイプを定義します。
- クエリタイプとミューテーションタイプ:これらは、すべてのGraphQLクエリのエントリポイントを定義する特別なタイプです。 すべてのGraphQLサービスには
query
タイプがあり、mutation
タイプがある場合とない場合があります。 - オブジェクトタイプ:これらはGraphQLスキーマの基本的なコンポーネントです。 これらは、GraphQLサービスからフェッチできるオブジェクトと、各オブジェクトが保持するフィールドを表します。
- スカラータイプ:これらは、GraphQLに標準で付属しているデフォルトのタイプです。 それらには、
Int
、Float
、String
、Boolean
、およびID
が含まれます。 - 列挙型:これらは、許可された値の特定のセットを定義する型です。
- 入力タイプ:これらはオブジェクトタイプに似ていますが、唯一の違いは、クエリに引数として渡すことができるオブジェクトを定義することです。
Union
、List
、Non-Null
、Interface
などの他のタイプがあります。 利用可能なGraphQLタイプのリストは、公式のGraphQLドキュメントにあります。
このアプリケーションでは、Note
モデルとNote
オブジェクトおよび入力タイプを作成します。 Note
モデルは、メモを格納するデータベーステーブルを表し、Note
オブジェクトと入力タイプは、Note
オブジェクトに存在するフィールドと引数を定義します。
まず、Railsが提供するgenerate model
サブコマンドを使用してNote
モデルを作成し、モデルの名前とその列およびデータ型を指定します。 ターミナルウィンドウで次のコマンドを実行します。
rails generate model note title:string:index body:text
このコマンドは、タイプstring
のtitle
とタイプtext
のbody
の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
を作成します。 有効なノートオブジェクトには、id
、title
、および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.rb
にnote_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
クラスを追加しました。 title
とbody
、どちらも文字列タイプ。
メモを取るアプリ用にモデルと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がリソースの作成、更新、削除のためのPOST
、PUT
、PATCH
、および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を操作するのに役立つガイドもいくつか含まれています。