この記事の内容
前回、GraphQL
の初心者がRailsでGraphQLを使えるようになるまでに調べたことをまとめて書きました。
GraphQLでデータを取得する作業のうち、
- 型の定義
- スキーマの書き方
までは記載できたのですが、肝心の**「どうやってデータを取得してくるか」**が長文になりすぎて書けなかったので、ここに記載します。
参考にしたのはこちらの記事と
こちらのチュートリアルなど
実際の実装方法は上記の記事の方が詳しいので、ここでは自分が担当したところでの実装で工夫していた点について主に記載していきます。
Apollo Clientを扱う
GraphQLの準備
既存の記事や公式チュートリアルの記載内容が大変優れているので、詳細はそちらに譲ります。ここではシンプルに手順だけ。
gem 'graphiql-rails'
こちらのgemをインストールして
$ bundle install
$ rails g graphql:install
のコマンドを実行したときに、routes.rb
に以下の内容が記載されていると思います。
Rails.application.routes.draw do
post "/graphql", to: "graphql#execute"
# 後略
end
これによって、/graphql
のURLにPOST
でアクセスすることでGraphQL
のメソッドが実行されます。
その後の方の定義などは前回の記事をご覧ください。
Apollo Clientの準備
apollo-client
をインストールし、
yarn add @apollo/client
appolo-client
を初期化します。
import {
ApolloClient,
InMemoryCache,
ApolloProvider
} from "@apollo/client";
// 解説します(★1)
const client = new ApolloClient({
uri: 'http://localhost:3000/graphql',
cache: new InMemoryCache()
});
// 解説します(★2)
export const App = () => {
return (
<ApolloProvider client={client} >
<Sample />
</ApolloProvider>
);
}
apollo-clientの初期化
まずはApolloClient()
メソッドを用いてapollo-client
を初期化します。
以下の2つが必須オプションです。
const client = new ApolloClient({
uri: 'http://localhost:3000/graphql',
cache: new InMemoryCache()
});
-
uri...
apollo-client
がGraphQL
の情報を受け取るところ。uri
かlink
のどちらかが必須で、両方あった場合はlinkが優先される。 -
cache...
apollo-client
がクエリの実行結果をローカルに保存するために使用するもの。@apollo/client
に同梱されているInMemoryCache
がおすすめ。
詳細なオプションはこちら。
このサンプルではApp.jsx
にて初期化をしていますが、初期化の内容を他のファイルに記載してApp.jsx
に読み込むこともできました。
ApolloProviderをアプリ上方に設置
そして、ApolloProvider
をアプリの可能な限り上方に設置します。これに先ほど初期化したApolloClient
のインスタンスを渡すことで下層のコンポーネントでapollo-client
が使えるようになります。
export const App = () => {
return (
<ApolloProvider client={client} >
<Sample />
</ ApolloProvider>
);
}
クエリの実行
クエリを実行するにはuseQuery()
メソッドを利用します。先程App.jsx
内で呼び出した、Sample.jsx
内で、このように記載します。
import React from 'react';
import { useQuery, gql } from "@apollo/client";
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
}
}
`;
export const Sample = () => {
const {loading, error, data} = useQuery(GET_USERS); // 解説します
if (loading) return 'ロード中....';
if (error) return `Error ${error.message}`;
return (
<>
{data.users.map(user => (
<div key={user.id}>
<h1>{user.name}</h1>
<h2>{user.email}</h2>
</div>
)}
</>
)
};
useQuery
メソッドはデフォルトで loading, error,dataの3つのプロパティを持つresult
オブジェクトを返します。
それを分割代入でそれぞれ{loading, error, data}
に代入しています。
-
loading...これが
true
である間、クエリはまだ実行中であり、結果はまだ返されていません。 -
error...クエリで1つ以上のエラーが発生した場合、このオブジェクトには、
graphQLErrors
の配列または単一のnetworkError
が含まれます。 -
result...
GraphQLクエリ
の実行結果を含むオブジェクトです。
useQueryの詳細な仕様はこちら
完成!
これで、ユーザーの情報を画面に描画することができたはずです。(既存のアプリは実像がかなり異なるので、抜け漏れがあるかもしれませんが、見つけ次第修正します)
その他、
- nestしたオブジェクトの
GET
- ID等を利用した単一オブジェクトの
GET
- mutationを利用した
POST
やUPDATE
メソッドの実行
はまだできていませんが、徐々に試したいと思います。(試し次第追記します)