我們今天要來介紹 Apollo Client ,這個套件是目前 GraphQL + React 最有名的套件之ㄧ,而且可以支援其他框架。
今天會簡單介紹如何設定以及利用之前的 project 來寫出一個支援 GraphQL 的前端網頁!
PS 如果懶得打開程式碼,也可以使用我之前推薦的 Code Sandbox ,然後打開一個 React 專案,雖然跟我本篇所用的 create-react-app
的資料結構有些不同,但對於有基本 React 概念的朋友應該不成問題。
開始之前我們要先開啟專案以及設定一些環境。
create-react-app
這邊我們選用最通用的 boilerplate facebook/create-react-app來做示範。
~ $ npx create-react-app react-graphql
~ $ cd react-graphql
~/react-graphql $ npm start
成功初始化專案後,你會得到一個基本的 react 專案。
src
: 主要程式碼
index.js
: 程式入口點,不過今天不會碰到App.js
: 主畫面public
: 放置一些 html, css 等 assets
index.html
: 頁面模板以及啟動後的畫面:
這裡我們需要以下的套件,
apollo-boost
裡面包裹了所有你設定 Apollo Client 所需要的套件。react-apollo
一層與 React 整合起來的 View 。graphql
用來 parse GraphQL query 的套件。資料參考: https://www.apollographql.com/docs/react/essentials/get-started.html#packages
~/react-graphql $ npm install --save apollo-boost react-apollo graphql
接著就用這些套件來設定 Apollo Client !
首先進入 src/App.js
,引入 ApolloClient
並作初始化,不過初始化時要傳入一個 GraphQL API uri 才能正確啟動 ApolloClient
,這邊有幾種選擇:
為 demo 方便,我就使用第三種,可以參考我之前寫好的 LaunchPad 範例 ,裡面有 user 跟 post ,大家可以直接引用裡面的 API 網址 (https://z5r11749r7.lp.gql.zone/graphql) ,或是登入 Github 後 Fork 我的範例。
// src/App.js
import ApolloClient from 'apollo-boost';
const client = new ApolloClient({
uri: 'https://z5r11749r7.lp.gql.zone/graphql'
});
接著同樣在 src/App.js
,我們將引入 ApolloProvider
進入 react , ApolloProvider
能夠連接 Apollo Client 與 React ,將 Apollo Client 索取到的資料引入 React 。
// src/App.js
import { ApolloProvider } from "react-apollo";
...
class App extends Component {
render() {
return (
<ApolloProvider client={client}>
<div>
<h2>My first Apollo app ?</h2>
</div>
</ApolloProvider>
);
}
}
需注意 ApolloProvider
預設下會建立自己的 Redux store 去管理 queries 與 queries 的結果,因此可以不需要再引入 Redux ,而如果是想將 ApolloProvider
引入現有 React & Redux 專案的話可參考 這個連結
有了 client
與 ApolloProvider
,接著讓我們看如何使用它們做 GraphQL query 。配合我所提供的 Apollo LaunchPad 範例,我將會利用這個 query :
讓我的網頁能夠呈現一個簡單的使用者列表:
讓我們先建立一個 src/Users.js
檔案來取得這個 user 列表並印出所有人的 name
。
這裡會用到兩個外部套件,分別為
import { gql } from "apollo-boost"
之前有用過 server 的應該對於 gql
tag 不陌生。這個 tag 可以直接幫我們建立一個 GraphQL query 物件。
import { Query } from "react-apollo"
這裡 react-apollo
提供了一個 Query
component 讓我們可以使用內建的 function 連接到外部 GraphQL API 。 Query
component 可以說是整個 Apollo 專案最重要的組成之一,而我們只需要傳入 query 物件進去 component props 就可以開始使用。
另外我們還需要在 component 內提供一個 render function , render function 裡面會代入 loading
, error
, data
三個參數供我們依照狀況做出不同 render。
想知道更多請看 官方文件
// src/Users.js
import React from "react";
import { Query } from "react-apollo";
import { gql } from "apollo-boost";
const getUsersQuery = gql`
{
users {
id
name
email
age
}
}
`;
const Users = () => (
<Query query={getUsersQuery}>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
// 最重要的就是從 data 裡面取得資料
const lists = data.users.map(currentUser => (
<li key={currentUser.id}> {currentUser.name} </li>
));
return (
<div>
<ul style={{ "list-style-type": "none" }}>{lists}</ul>
</div>
);
}}
</Query>
);
export default Users;
有了 User name 列表後,讓我們將他引入 src/App.js
。
// src/App.js
...
import Users from "./Users";
...
function App() {
return (
<ApolloProvider client={client}>
<div>
<Users />
</div>
</ApolloProvider>
);
}
啟動 npm start
後可以看見成果了!
讓我們把剩下的資料顯示出來並編排好。回到 src/Users.js
,把 user 其他資料也顯示出來。
// src/User.js
const Users = () => (
<Query query={getUsersQuery}>
{({ loading, error, data }) => {
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
const lists = data.users.map(currentUser => (
<li key={currentUser.id}>
<li>id: {currentUser.id}</li>
<li>name: {currentUser.name} </li>
<li>email: {currentUser.email}</li>
<li>age: {currentUser.age}</li>
<br />
</li>
));
return (
<div>
<ul style={{ "list-style-type": "none" }}>{lists}</ul>
</div>
);
}}
</Query>
);
就可以得到結果:
是不是很簡單呢!之後會講解如何應用到 stage management 。另外我也有在底下附上本篇的程式碼範例:
先說明一下,其實 Apollo Client 也跟 Apollo Server 一樣,有分第一代跟第二代。 Apollo Server 1 只是一個 GraphQL middleware 而已,而 Apollo Server 2 整合 express
, body-parser
, graphql-tag
, graphql-tools
等工具,一次滿足你所有需求。
同樣的, Apollo Client 也僅有結合 GraphQL 與 Redux store 管理功能而已,而第二代的 Apollo Boost 則是將 Apollo Client 以及其他常用套件如 apollo-cache-inmemory
, apollo-link-http
, apollo-link-error
, apollo-link-state
等等,並且支援了 Query 和 Mutation Component 支援。
提到這些主要是想要提醒如果大家在網路上看到的其他範例明明都用 Apollo Client 但用法卻大不同,那就可能是因為使用的版本不同。
Reference: