Ruby on Rails & GraphQLの環境構築と実装
IT技術
はじめに
RailsとGraphQLで開発しているプロジェクトに参画したのですが、
環境構築を1からしたことがなかったので、やり方をまとめていきたいと思います!
GraphQLとは?
GraphQLを導入することで、1つのエンドポイントで色々なレスポンスを返すことができます。
どういうレスポンスが必要なのかをクライアント側で指定することができ、その指定された値だけを返す処理はGraphQLが行ってくれるので、このページではこの値は不要だとか、そういった面倒なことをバックエンド側で考える必要がなくなります。
Rails環境の構築
まずはGraphQL導入の前に、Rails環境構築をしていきましょう。
Controllerを使って、DBの値を返すようなAPIを作ります。
バージョン情報
1$ rails -v
2 Rails 7.0.3
3$ ruby -v
4 ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]
Hello Worldまで
以下コマンドを入力し、Ruby on Railsのプロジェクトを作成しましょう。
1$ rails new test_graphql_api
そうしたら、HelloWorldを返却する用のControllerを実装します。
app/controllers下に以下ファイルを追加しましょう。
1class HelloController < ApplicationController
2 def hello
3 render json: { message: "Hello World!" }
4 end
5end
あとはconfig/routes.rbにhelloの情報を追加し、
1Rails.application.routes.draw do
2 root "hello#hello"
3end
rails s コマンドを実行して、起動したサーバーにアクセスすると、HelloControllerで実装したJsonが返ってくるようになりました!
DBを扱ったAPIを作成する
デフォルトのrailsアプリではsqlite3が入っているので、これを使っていきます。
以下のコマンドでUserモデルファイルを作成し、DBに反映させましょう。
1$ rails g model User name:string age:integer
2$ rails db:migrate
もしモデルとテーブルを作成し直したい場合は以下コマンドでいけます。
1$ rails d model User
2$ rails g model User ...
3$ rails db:migrate:reset
これでUsersテーブルができたので、Usersテーブルを使った以下のAPIを実装します。
- Userの追加
- Userの一覧取得
- 特定Userの取得
まずはUser関連を扱うControllerクラスを作成しましょう!
1class UsersController < ApplicationController
2 skip_before_action :verify_authenticity_token
3
4 # Userの一覧取得
5 def index
6 users = User.all
7 render json: users
8 end
9
10 # Userの追加
11 def add
12 user = User.create(name: params["name"], age: params["age"])
13 render json: user
14 end
15
16 # 特定Userの取得
17 def user
18 user = User.find(params[:id])
19 render json: user
20 end
21end
User用のルーティングも設定します。
1Rails.application.routes.draw do
2 root "hello#hello"
3
4 get 'users', to: 'users#index'
5 get 'users/:id', to: 'users#user'
6 post 'users', to: 'users#add'
7end
これで一通りの実装が完了しました!
動作確認
Usersテーブルに何も入ってない状態になっているので、まずはUserデータを追加するAPIを叩きましょう。
適当なUserをいくつか追加しておきます。
これでUserテーブルにデータが追加されたので、他のAPIも叩いてみましょう。
無事取得できましたね!
GraphQLに置き換える
ここからが本題です。
さきほどのUsersControllerをGraphlQL化していきましょう!
まずはGraphQLのインストールからです。
1gem 'graphql'
2gem 'graphiql-rails' # ブラウザ上でGraphQLを確認できるようにするやつ
Gemfileに上記を入れて、bundle install しましょう。
その後以下コマンドを叩くと、GraphQL用のController作成やroutes.rbの設定など自動で行ってくれます。
1$ rails g graphql:install
あとは上記コマンドによって作成されたapp/graphql下で、GraphQLのAPIを作成していきましょう。
GraphQL用のUserモデルの作成
まずはGraphQL用のUserモデルを作成します。
以下コマンドによって、DBのテーブルを参照してapp/graphql/types下に作成されます。
1$ rails g graphql:object User
1# frozen_string_literal: true
2
3module Types
4 class UserType < Types::BaseObject
5 field :id, ID, null: false
6 field :name, String
7 field :age, Integer
8 field :created_at, GraphQL::Types::ISO8601DateTime, null: false
9 field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
10 end
11end
まずは実装が単純な「Userの一覧取得」から実装していきましょう。
Userの一覧取得の実装
app/graphql下にqueries/resolversフォルダを作成し、以下のファイルを追加します。
1module Queries
2 module Resolvers
3 class Users < GraphQL::Schema::Resolver
4 type [Types::UserType], null: false
5 description "Userの一覧取得"
6
7 def resolve
8 ::User.all
9 end
10 end
11 end
12end
そうしたら以下のコードをquery_type.rbに書き足すだけです。
1field :users, resolver: Queries::Resolvers::Users
Resolverを使わなくてもquery_type.rbに直接書き足していくだけでもいいのですが、実装するAPIが多くなると肥大化してしまうため、分離しています。
これでUserの一覧取得は実装できましたので、graphiqlで確認してみましょう!
左側がリクエストで、右側でレスポンスになります。
さきほどのHTTPリクエストと同じようなデータが取得できていますね!
GraphQLでは、リクエスト中のnameやageを削除することで、レスポンスを操作することが可能です。
次にリクエスト時にidが必要な「特定Userの取得」を実装してみましょう。
特定Userの取得の実装
ほとんどUserの一覧取得と同じ感じで実装できます。
まずはResolverを追加しましょう。
1module Queries
2 module Resolvers
3 class User < GraphQL::Schema::Resolver
4 type Types::UserType, null: false
5 description "特定Userの取得"
6
7 argument :id, String, required: true, description: "Userのid"
8
9 def resolve(params)
10 # ::Userとしているのは、Queries::Resolvers::Userとして呼ばれるのを防ぐ為
11 ::User.find(params[:id])
12 end
13 end
14 end
15end
最後にquery_type.rbにUserの定義を追加します。
1field :user, resolver: Queries::Resolvers::User
これで実装できましたので、graphiqlで確認してみましょう!
HTTPリクエストと同じく、id:1の指定でhoge美のデータが取得できましたね!
最後にUserの追加を実装していきましょう。
Userの追加
データの追加にはMutationが利用できます。
以下コマンドを実行して、ファイルを作成しましょう。
1$ rails g graphql:mutation AddUser
これによってapp/graphql/mutations/add_user.rbが作成されたので、ここを編集していきます。
1module Mutations
2 class AddUser < BaseMutation
3 field :user, Types::UserType, null: false
4
5 argument :name, String, required: true
6 argument :age, Integer, required: true
7
8 def resolve(params)
9 user = User.create(name: params[:name], age: params[:age])
10 {
11 "user": user
12 }
13 end
14 end
15end
ほとんどResolverで書いたやつと同じですね。
注意点としては、レスポンスにフィールド名を指定する必要があるため、Userモデルそのままで返すとエラーになっちゃう点です。
query_type.rbと同じくmutation_type.rbも存在しますが、ここへの記述はさきほどのコマンド実行によって完了しています。
1field :add_user, mutation: Mutations::AddUser
これで実装は完了したので、graphiqlで確認していきましょう!
いろいろ試していたのでidの数値が大きくなっていますが、ここまで順調に進んでいれば3になっていると思います。
addUserをした後にusersを叩くと、しっかりと追加されていることが確認できますね!
まとめ
ControllerにAPIを実装するのと、そう変わらない手間でGraphQLAPIの作成ができたと思います。
冒頭で述べたGraphQLの利点以外にも、APIごとに必要なパラメータやレスポンスの型などが、MutationやResolverでわかりやすくなってる点が個人的には好みなところです。
今回のコードは以下のリポジトリにまとめてありますので、ぜひ確認してみてください!
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
おすすめ記事
immichを知ってほしい
2024.10.31