この記事では、GraphQLとRailsを使って、クエリを使ってデータベースからToDoを送り返すAPIを構築します。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
アリババクラウドコミュニティブログ執筆者 ダニエル・ショトンワ氏
この記事では、クエリを使ってデータベースからTodoを送信するAPIをAlibaba Cloud上でGraphQLとRailsを使って構築する方法を紹介します。さて、始める前にいくつかのことをクリアにしておきましょう。
出典:fiver.com
まず第一に、あなたはすでに知っているはずです - 特にあなたが最初の場所でここをクリックしたという事実を考えると - Railsは、短時間でWebアプリケーションを作成するための非常に人気のあるフレームワークです。開発者はバックエンド用のAPIを作成することでアプリケーションのプロセスやメカニズムを分離し、好みのライブラリを使用する傾向があります。私たち自身もこの傾向に従うことになるでしょう。
次に、おそらく、ご存知の方も多いと思いますが、GraphQLもあります。GraphQLとは何かについては、https://graphql.org/ からのこの定義がよく説明してくれています。
GraphQLはAPI用のクエリ言語であり、既存のデータを使ってクエリを実行するためのランタイムです。GraphQLは、API内のデータを完全かつ理解しやすい形で記述し、クライアントが必要とするものを正確に求めることができるようにします。
GraphOLとRailsを使用するだけでなく、このチュートリアルではUbuntu 16.04でインストールされたElastic Compute Service (ECS)インスタンスを使用してアプリケーションをデプロイします。そのため、先に進む前にAlibaba Cloudのアカウントでサインアップしていることを確認してください。
#前提条件
始める前に、ECSインスタンスがすでにセットアップされていることを確認してください。まだ設定していない場合は、Alibaba Cloud の関連ドキュメントをチェックして、簡単に設定できるようにしてください。
次に、ローカルマシンにrubyのバージョン2.2以降、およびrailsのバージョン5以降がインストールされていることを確認してください。
ruby のバージョンが最新でない場合は、rvm や rbenv などの ruby バージョンマネージャを使ってアップデートすることができます。また、rubyのバージョンを更新するには、以下の対応するコマンドのいずれかを呼び出すことができます。
$ rvm install "ruby-2.4.6"
or
$ rbenv install 2.4.6
あるいはこのように実行して rails をアップデートすることもできます。
$ gem update rails
そして...必要なのはこれだけです! これで、RailsでシンプルなGraphQL APIを構築する準備が整いました。
#手順
###データベースとテキストエディタの作成
このチュートリアルの一環として、以下のツールを持っていることも期待されています。
- Postgres データベース
- テキストエディタ
そのためには、コマンドラインでrailsを実行して、Postgresデータベースを使用した基本的なRailsアプリケーションに必要なすべてのファイルとフォルダを作成します。
$ rails new todo-app `--database=postgresql`
$ cd todo-app
###Gemの設定
その間に、次のようにしましょう。 Railsでgraphqlアプリケーションを作成するには、graphqlというgemを追加する必要があります。そして、このgemをGemfileに追加します。
gem’graphql'
コマンドで行うことができます。そして、$ bundle install
コマンドを実行してgemをインストールします。これでgemがインストールされているはずです。次に、GraphQL APIに必要なすべてのファイルとフォルダを作成するために、以下のコマンドを実行します。
$ rails generate graphql:install
これを実行すると、gemfileにgraphiql-rails
gemが追加されます。このgemを使用することで、APIとの対話が可能になります。
###データベースの設定
アプリケーションをPostgresデータベースに接続するには、config/database.yml
ファイルにアクセスし、テスト環境と開発環境の両方にPostgresのユーザ名とパスワードを追加します。
development:
<<: *default
database: todo_app_development
username: YOUR_POSTGRES_USERNAME
password: YOUR_POSTGRES_PASSWORD
test:
<<: *default
database: todo_app_development
username: YOUR_POSTGRES_USERNAME
password: YOUR_POSTGRES_PASSWORD
$ rails db:create
コマンドを実行してデータベースを作成し、$ rails server
コマンドでサーバを実行します。
このルート localhost:3000/graphiql
にアクセスすると、graphql クライアントが表示され、これを使って graphql サーバにリクエストを送ることができます。
###モデルの作成
このtodoアプリケーションでは、title
とdescription
の2つのフィールドを持つtodoテーブルを作成します。実行してモデルを作成します。
$ rails generate model Todo title:string description:text
データベースに入力する前に、タイトルと説明フィールドが常に指定されていることを確認することで、検証を行うことができます。models/todos.rb
に移動し、rails validationを追加します。
class Todo < ApplicationRecord
validates :title, presence: true
validates :description, presence: true
end
$ rails db:migrate
コマンドを実行してマイグレーションを実行し、rails consoleを使用してデータベースにデータを追加します。
$ rails console
>- Todo.create(title: 'Sample title', description: 'Sample Description')
GraphQLスキーマには3つの特別な_ルート型があり、これらはQuery
, Mutation
、Subscription
と呼ばれています。
- Query`: データベースからデータを取得できるようにするグラフQL機能です。Rest APIのGETコールのように動作します。
-
Mutation
: クライアントがデータベースにデータを送信できるようにするグラフQL機能です。REST APIのPOST
、PUT
、DELETE
操作のように動作します。 -
Subscription
:サブスクリプションは、特定のイベントが発生したときにサーバーがクライアントにデータを送信することができるようにするグラフQL機能です。サブスクリプションは通常 WebSocket で実装されます。アクション ケーブル
###クエリの作成
それでは、データベースからすべてのTODOを取得するための最初のクエリを作成してみましょう。新しいファイル app/graphql/types/todo_type.rb
を作成して todos 用の新しいタイプを作成します。
#app/graphql/types/todo_type.rb
module Types
class TodoType < Types::BaseObject
field :title, String, null: false
field :description, String, null: false
end
end
BaseObject
を継承しているので、app/graphql/types/base_object.rb
を参照してください。GraphQL::Schema::Object
を書く代わりにGraphqlのSchema typeを継承しているので、BaseObject
を継承するだけでオブジェクトSchemaを作成するのに必要な属性が全て得られます。
次のステップは、すべてのTodoを取得するために使用するquery typeを作成することです。app/graphql/types/query_type.rb
に移動します。すべてのTodoを取得するために、クエリタイプに :all_todos
という新しいフィールドを追加します。
# app/graphql/types/query_type
field :all_todos, [TodoType], null: false,
description: "Returns all todos"
def all_todos
Todo.all
end
[TodoType]
の部分を追加したのは、Todoのリストを期待しているからです。さて、ブラウザに向かい、このようなクエリを書きます。
query {
allTodos {
title
description
}
}
これで、データベース内のすべてのTodoを返してくれるので、タイトルを省略して説明を求めることもできますし、その逆もできます。
###Mutationの追加
次はTodoを作成するための変異を追加します。その前に、GraphQL::Schema::Mutation
を継承したBaseMutation
クラスを作成してみましょう。これで今後はBaseMutation
を継承できるようになります。
次に、apps/graphql/mutations
フォルダ内にbase_mutation.rb
というファイルを新規作成し、このコードを追加します。
# app/graphql/mutations/base_mutation.rb
module Mutations
class BaseMutation < GraphQL::Schema::Mutation
null false
end
end
では、todoを追加するための変異を作成してみましょう。そのために、mutationフォルダ内にadd_todo.rb
というファイルを作成し、このコードを追加します。
#app/graphql/mutations/add_todo.rb
module Mutations
class AddTodo < BaseMutation
argument :title, String, required: true
argument :description, String, required: true
type Types::TodoType
def resolve(title: nil, description: nil)
Todo.create!(title: title, description: description)
rescue ActiveRecord::RecordInvalid => e
GraphQL::ExecutionError.new(e.record.errors.full_messages.
join(','))
end
end
end
このコードは、必要な引数と返される型を指定して AddTodo
Mutationsを追加します。
変異のコードにはレスキューブロックがあります。railsのGraphQLには、GraphQL::Execution.new(error_messages)
というエラー処理ブロックがあります。
作成したmutationをmutation typeに追加して、クライアントからアクセスできるようにします。
# app/graphql/types/mutation_type.rb
module Types
class MutationType < Types::BaseObject
field :add_todo, mutation: Mutations::AddTodo
end
end
このクエリを使っていくつかのTodoを作成して、ブラウザ上でテストしてみてください。
mutation {
addTodo(title: "New Todo", description: "I will eat rice") {
title
description
}
}
#GraphQLの導入
すでに持っているはずのAlibaba ECSインスタンスを使ってGraphQL APIをデプロイします。PassengerとNginxを使ってRailsアプリケーションを簡単にデプロイする方法は、このチュートリアルに従ってください。
そしてそれをデプロイした状態で。これでいくつかのTODOSを作成し、クエリを使ってデータベースからTODOSを取得する方法もわかりました。ユーザーがログインしたり、削除したり、ToDoを更新したりできるようにするための認可と認証を行うための別の記事を書く予定です。
Alibaba Cloudのアカウントを持っていない?アカウントにサインアップして、最大1200ドル相当の40以上の製品を無料でお試しください。詳細は、Alibaba Cloudの利用開始をご覧ください。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ