Apollo GraphQL 快速上手
Graphql vs RestAPI
在訊息取得和資料交換上,rest api 已經是業界的標準,透過其規格,我們可以快速輕易的取得對應的資訊。
而相較於成熟的rest api,GraphQL 則是仍在持續發展中的技術。
但從本質上來說,GraphQL的重點是針對性能和靈活性進行優化,這些彈性及優化也許能為很適切的符合某些情境
1、強型別語言
可以明確的定義資料型態,型別錯誤會直接被阻擋,也可以方便的自動產出文件--程式即文檔
2、減少資訊短缺或資訊過度獲取(Over Fetching / Under Fetching)的情況
類似SQL語言的方式,使用者可以精確的自定查詢調件、及回傳內容
3、相容性問題
不論是前端使用,和rest api混搭開發,或透過系統架構方式(如micro service架構),統一資料交換接口,都可以讓開發更有彈性
在整合應用上,Apollo Community 已經提供相當的工具及解決方案,
這邊介紹 apollo-server 應用,做為快速進入GraphQL開發世界的範例
開始使用
安裝上前我們要先確認nodejs已安裝完成,npm可正常使用,然後可以簡單的5個步驟來完成體驗
1、建立測試目錄
mkdir apolloDemo
2、npm 初使化
cd apolloDemo
npm init --yes
3、安裝apollo-server 及 graphql
npm install apollo-server graphql
4、建立index.js
vim index.js
內容設定如下,我們先依官網提供之範例建立:
|
5、啟動服務
node index.js
服務default設定,啟動在4000 port。
現在我們就可以連進去網頁看看精美的apollo介面了。
介面操作
左方是我們輸入參數的地方,這邊我們使用 query 的語法,將books 下的 title 及 author一次全部取回來
按下向右三角型圖式,我們就可以看到取回的結果。
當然,graqhql彈性空間就是我們可依不同的query 要求,我們可以取回想要的欄位置
現在我們在回頭來看一下index.js設定的內容
1、typeDefs下,我們定義了欄位的內容(Book)及查詢的條件(Query),
GraphQL 有定義五種型別的純量型態:Int、String、Float、Boolean、ID
2、範例上設定了靜態的資料來源(books),包含兩本書的書名及作法
3、最後設定一組解析器(resolver),預設無指定查詢回傳條件
以上就完成了一個最簡單的graphQL apollo 設定及查詢
加入查詢條件
既然是有彈性的查詢語言,我們就應該能更有效率的使用"查詢"及"條件"
盡量發揮其 Query Language 的特性,首先我們來改寫設定:
我們定義一組新資料結構:
type User { id: ID! name: String } type Query { user(id: ID!): User, users:[User] } |
User下包含兩個欄位,id:唯一鍵值(ID!);name:字串(String)
Query 包含了使用者id查詢user(id: ID!): User
及 查詢使用者列表users:[User]
user 寫入4筆資料:
const users = [ { id: '1', name: 'Ryan', gender: 'M' }, { id: '2', name: 'Annisa', gender: 'F' }, { id: '3', name: 'James', gender: 'M' }, { id: '4', name: 'Maggie', gender: 'F' } ]; |
最後,解析器定義查詢回傳的條件,符合query動作時,我們對應的解析回傳內容
const resolvers = { Query: { user(parent, args, context, info) { return users.find(user => user.id === args.id); }, users: () =>users } } |
再次重新啟動服務node index.js
首先我們更新query為 users{id name}
已經可以看到資料結構的更新,
然後試著下下新的query語法查詢條件[id查詢],user(id:"1"){id name}
就完成透過id查詢特定對像了。
應用範例
現在 Apollo GraphQL已經建好了,那我們該如何透過程式來呼叫GraphQL資料呢?
目前,GraphQL支援的程式語言範圍已經相當完整了。
我們可以使用javascript的fetch功能來做一個簡單的呼叫範例
<script> const query = 'query{users{id,name}}'; const url = "http://localhost:4000/"; const opts = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query }) }; fetch(url, opts) .then(res => res.json()) .then(console.log) .catch(console.error); </script> |
就可以快速得到以下的結果
參考資料:
https://graphql.org/blog/
https://moonhighway.com/fetching-data-from-a-graphql-api