GraphQLとは何か
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
GraphQLは、APIのクエリ言語であり、既存のデータを使用してこれらのクエリを実行するためのランタイムです。GraphQLは、API内のデータの完全でわかりやすい説明を提供し、クライアントが必要なものだけを正確に要求できるようにし、時間をかけてAPIを進化させやすくし、強力な開発者ツールを有効にします。
引用: https://graphql.org/
要するに、クエリ言語でAPIのドキュメント、問い合わせを定義することで我々が開発しているAPIの変更を容易にしてくれるものです
GraphQLでできる事
- graphqlドキュメントを介してフロント・バック間の分業がしやすくなる
- バックエンド
- DBのスキーマからgraphqlのAPI定義(ドキュメント)を自動生成できる
- フロントエンド
- バックエンドで自動生成したドキュメントからさらに自動で型生成することができる
→スキーマ変更を伴う改修をした時の実装コストが下がる!!(かもしれない
ハンズオン
ユーザーを取得するAPIを実装するケースを考えます
バックエンド
登場人物
- graphql-ruby
- graphiql-rails
前提として、graphqlのAPI開発に必要なファイル群を自動生成します
rails g graphql:install
実際のAPI開発に進みます。今回はUserを取得するエンドポイントを考えます
まず User の オブジェクトを生成します
rails g graphql:object User
するとusersテーブルのスキーマからGraphQL Type相当のコードが自動生成されます。
生成されたコードを見る
# frozen_string_literal: true
module Types
class UserType < Types::BaseObject
field :id, ID, null: false
field :email, String, null: false
# こういう露出したくないフィールドは削る
# field :crypted_password, String
# field :salt, String
field :is_verified, Boolean, null: false
field :deleted_at, GraphQL::Types::ISO8601DateTime
field :name_sei, String, null: false
field :name_mid, String, null: false
field :name_mei, String, null: false
...
# associationは自分で追加してあげる必要がある(要N+1対策
field :activities, [Types::ActivitiyType], null: false
end
end
graphql/query_type.rb でエンドポイントを定義します
field :users, [Types::UserType], null: false do
description '全ユーザー返す'
end
def users
User.all
end
次に graphql スキーマを吐かせないといけないのですが、標準でそのような rakeタスクは用意されていないので、自分で作る必要があります。
require "graphql/rake_task"
GraphQL::RakeTask.new(schema_name: "MySchema")
このrakeタスクを作成してから
$ rails graphql:schema:idl
を叩くと graphqlドキュメントが生成されます
こちら
type Query {
"""
全てユーザー返す
"""
users: [User!]!
}
type User {
createdAt: ISO8601DateTime!
deletedAt: ISO8601DateTime
email: String!
id: ID!
nameSei: String!
nameMid: String!
nameMei: String!
updatedAt: ISO8601DateTime!
...
}
フロントエンド
登場人物
- urql
- graphql-codegen
まずはクエリを定義します。
export const UsersQuery = graphql(/* GraphQL query */ `
query UserQuery {
users {
id,
email,
nameSei,
nameMid,
nameMei
}
}
`);
次にgraphqlの設定ファイルを置きます
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: './schema.graphql',
documents: ['src/**/*.{ts,tsx}'],
generates: {
'./src/graphql': {
preset: 'client',
plugins: []
}
}
}
export default config
これで
$ yarn graphql-codegen
すると型が自動生成されます。(自動生成された型は膨大なので割愛
N+1対策
本筋とは逸れますが、railsでgraphqlを使う場合、includes
preload
してもはN+1が起きてしまいます。
そこで、graphql-batchというライブラリを利用することでN+1を回避することができます。
以下の記事がとても参考になったので供養