✨
Rails:GraphQL API の構築手順
Rails で GraphQL API を構築する手順を整理します。
公式ドキュメント
前提
こちらの手順に従い、開発環境を構築していることを前提とします。
1. GraphQL のセットアップ
インストール
graphql をインストールします。
project-backend/Gemfile
+ gem 'graphql'
起動している backend のプロセス名を確認し、コンテナ内に入ります。
docker ps
docker exec -it project_backend_1 sh
インストールコマンドを実行します。
bundle install
bundle exec rails g graphql:install
必要なファイル群が app/graphql
下に生成されます。
2. GraphQL クエリ
リソース Post
のデータを GraphQL で取得できるようにします。
型の作成
リソース Post
の型を PostType
で定義します。
project-backend/app/graphql/types/post_type.rb
module Types
class PostType < Types::BaseObject
description "A blog post"
field :id, ID, null: false
field :title, String, null: false
field :body, String, null: false
end
end
クエリの作成
続いて、クエリロジックを定義します。
BaseQuery
project-backend/app/graphql/queries/base_query.rb
module Queries
class BaseQuery < GraphQL::Schema::Resolver; end
end
- クエリ関連のファイルは
app/graphql/queries
にまとめます。
PostsQuery
Post
の一覧を取得。
project-backend/app/graphql/queries/posts_query.rb
module Queries
class PostsQuery < Queries::BaseQuery
type [Types::PostType], null: false
def resolve
Post.limit(50)
end
end
end
PostQuery
ID指定で該当する Post
を1件取得。
project-backend/app/graphql/queries/post_query.rb
module Queries
class PostQuery < Queries::BaseQuery
type Types::PostType, null: false
argument :id, ID, required: true
def resolve(id:)
Post.find(id)
end
end
end
定義したクエリを QueryType
に記載し、ルートクエリとして取得できるようにします。
project-backend/app/graphql/types/query_type.rb
module Types
class QueryType < Types::BaseObject
# Add `node(id: ID!) and `nodes(ids: [ID!]!)`
include GraphQL::Types::Relay::HasNodeField
include GraphQL::Types::Relay::HasNodesField
# Add root-level fields here.
# They will be entry points for queries on your schema.
field :posts, resolver: Queries::PostsQuery
field :post, resolver: Queries::PostQuery
end
end
GraphiQL で動作確認
テストツール「GraphiQL」で動作確認してみます。
field :posts
field :post
問題なく動いています。
3. GraphQL ミューテーション
リソース Post
のデータを GraphQL で更新できるようにします。
ミューテーションの作成
PostInputType
更新処理に必要なインプットデータの型を定義します。
project-backend/app/graphql/types/input/post_input_type.rb
module Types
module Input
class PostInputType < GraphQL::Schema::InputObject
argument :id, Int, required: true
argument :title, String, required: false
argument :body, String, required: false
end
end
end
- インプットデータの型は
app/graphql/types/input
にまとめます。
UpdatePost
該当する Post
を更新する処理を定義します。
project-backend/app/graphql/mutations/update_post.rb
module Mutations
class UpdatePost < Mutations::BaseMutation
argument :params, Types::Input::PostInputType, required: true
def resolve(params:)
post_params = params.to_h
post = Post.find(post_params.delete(:id))
post.update!(post_params.compact)
post
end
end
end
- ミューテーションは
app/graphql/mutations
にまとめます。
MutationType
定義した更新処理を MutationType
に記載します。
project-backend/app/graphql/types/mutation_type.rb
module Types
class MutationType < Types::BaseObject
field :update_post, Types::PostType, mutation: Mutations::UpdatePost
end
end
GraphiQL で動作確認
テストツール「GraphiQL」で動作確認してみます。
変数
{
"params": {
"id": 1,
"title": "Title updated from GraphQL"
}
}
クエリ
mutation($params: PostInputType!) {
updatePost(input: { params: $params }) {
id
title
}
}
- キー
input
にオブジェクトを持たせないとエラーが出ます。
実行結果
問題なく更新されています。
次のステップ
フロントエンド Apollo Client の構築手順をまとめています。
Discussion