GraphQLとRailsでAPIを構築する方法


この記事では、GraphQLRailsを使って、クエリを使ってデータベースから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 のバージョンが最新でない場合は、rvmrbenv などの 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アプリケーションでは、titledescriptionの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, MutationSubscriptionと呼ばれています。

  • Query`: データベースからデータを取得できるようにするグラフQL機能です。Rest APIのGETコールのように動作します。
  • Mutation: クライアントがデータベースにデータを送信できるようにするグラフQL機能です。REST APIのPOSTPUTDELETE操作のように動作します。
  • 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ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ