こんにちは、mabuiです。
GraphQLをクライアントで使いやすくするためのライブラリ、Apollo Clientのチュートリアルを手を動かしつつ紹介して、今後のサービス開発に活かしていこうと思います。
なお、チュートリアルはReactで解説されています。
チュートリアルページ - Get started
インストール
動作に必要なパッケージ群のインストールです。
1 2 |
npm install apollo-boost react-apollo graphql --save |
- apollo-boost
Apollo Clientのセットアップに必要なメモリキャッシュ、ローカル状態管理、エラー処理などのパッケージが含まれています。
- react-apollos
ReactコンポーネントからGraphQLサーバにアクセスするパッケージです。
- graphql
GraphQLクエリのパーサーです。
チュートリアルのコードを実行する場合は、CodeSandboxを使用するか、create-react-appで新規Reactプロジェクトを作成するのがいいでしょう。
クライアント作成
ではApolloクライアントのコードを書いていきましょう。
クライアントのオブジェクト生成にはGraphQLサーバーのエンドポイント(=url)が必要です。
公式が用意してくれているエンドポイントを使用します。
エンドポイントを指定しない場合は、ローカルの/graphql
エンドポイントが指定されます。
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; import ApolloClient from "apollo-boost"; import gql from "graphql-tag"; const client = new ApolloClient({ uri: "https://w5xlvm3vzz.lp.gql.zone/graphql" }); client.query({ query: gql` { rates(currency: "USD") { currency } } ` }) .then(result => console.log(result)); class App extends Component { render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } } export default App; |
create-react-appで生成したAppコンポーネントのファイル内に埋め込んでquery
を実行しています。
ApolloClient
はapollo-boost
パッケージから、
クエリ文字列を解析するgql
関数はgraphql-tag
パッケージからそれぞれインポートします。
npm start
でreact appを起動すると、コンソールのログでクエリ結果が出力されています。
ここまで素のJavaScriptでGraphQLのクエリを実行したのみですが、
Reactと統合することでクエリをUIコンポーネント内で扱いやすくすることができます。
Reactの導入
ではApollo ClientをReactに導入していきましょう。
react-apollo
パッケージからApolloProvider
コンポーネントをインポートして、
その他のコンポーネントを囲んで親子関係を作ることで、子コンポーネントからいつでもGraphQLにアクセスできるようになります。
create-react-appで生成したコードの場合、最上位のコンポーネントであるApp
コンポーネントの内部コンポーネントを囲むように配置することで、アプリケーション全体で使用できるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import React, { Component } from 'react'; import './App.css'; import ApolloClient from "apollo-boost"; import { ApolloProvider } from "react-apollo"; const client = new ApolloClient({ uri: "https://w5xlvm3vzz.lp.gql.zone/graphql" }); class App extends Component { render() { return ( <ApolloProvider client={client}> <div> <h2>My first Apollo app </h2> </div> </ApolloProvider> ); } } export default App; |
以上でコンポーネントからクエリを発行する準備ができました。
リクエストデータ
では、クエリを操作していきます。
Query
コンポーネントのquery
プロパティ(=query prop
)にgql
関数を使用してクエリ文字列のオブジェクトを渡します。
Query
コンポーネントの内部ではレンダリングする要素を記述でき、エラーとローディングの状態を追跡してloading prop
と error prop
を、クエリ結果を data prop
としてそれぞれ利用できます。
Apollo Clientの実装内部ではコンポーネント内部の記述を、Query
コンポーネントの値に関数を持つchildren
プロパティ(=children prop
)に渡してレンダリングする要素を知らせており、
こういったコンポーネントのプロパティの値を関数とするやり方をRender Props
と呼びます。
下記のコードではprops
からloading
, error
, data
をそれぞれアロー関数の引数に渡して処理しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
import React, { Component } from 'react'; import './App.css'; import ApolloClient from "apollo-boost"; import { ApolloProvider } from "react-apollo"; import { Query } from "react-apollo"; import gql from "graphql-tag"; const client = new ApolloClient({ uri: "https://w5xlvm3vzz.lp.gql.zone/graphql" }); const ExchangeRates = () => ( <Query query={gql` { rates(currency: "USD") { currency rate } } `} > {({ loading, error, data }) => { if (loading) return <p>Loading...</p>; if (error) return <p>Error :(</p>; return data.rates.map(({ currency, rate }) => ( <div key={currency}> <p>{`${currency}: ${rate}`}</p> </div> )); }} </Query> ); class App extends Component { render() { return ( <ApolloProvider client={client}> <div> <h2>My first Apollo app </h2> <ExchangeRates/> </div> </ApolloProvider> ); } } export default App; |
クエリの実行結果はExchangeRates
コンポーネントに出力されます。
ここまででReactのクエリコンポーネントが作成できました。
お疲れ様でした!🍻