GraphQL 是什麼呢? REST、RESTful API 在 API 界誰不認識呢?
為什麼全世界的工程師都要用 GraphQL 取代傳統 API 呢? 這個由 Facebook 推出的東東有什麼優點呢? 簡單說明 GraphQL 並提供 PHP Laravel 結合 GraphQL 的實做範例.
延伸舊文: 麻瓜也看的懂的 什麼是 API? API 是什麼?
index:
- 前言/需求情境
- GraphQL 有什麼優點?
- GraphQL 的缺點
- Laravel-PHP與GraphQL API試用與實作
(👆 我己經知道什麼是 GraphQL,廢話少說馬上做!) - 總結 / 結論
- 延伸 / 說明 / 參考
前言
目前 Netflix、Airbnb、GitHub、Twitter、Pinrerest、PayPal、IBM 和台灣的 iCHEF 已經使用 GraphQL, 這麼多公司使用, 我們一定也要跟風用一下. 😎
Wiki 說什麼是 GraphQL: https://zh.wikipedia.org/wiki/GraphQL (tl;dr)
也可參考 延伸 / 說明 / 參考 – GraphQL 入門
需求情境
網站分桌面版、行動版, APP 也有 iOS, Android. 細分的話還有一般使用者和管理員用的操作介面.
每個環節、畫面都會用到一樣的資料.
但是畫面上顯示、取用的 資料欄位
可就不一樣了…
iOS APP 需要使用者的寵物資料、Android APP 則要使用者全家人的資料, mobile 網站因為畫面小所以只要使用者姓名, 而桌面版網站因為每個人都是 4k 螢幕所有資料全都要 😂
天啊!!
後端工程師們要開幾支 API 呢? 前端用、後台用? mobile 網站? APP 專用?
這樣維護、開發、管理這些 API 有多累人.
使用 restful api 的時候可能就會出現…
/user/123
/user/123?platform=ios
/user/123?platform=web&fields=id,name
/user/123?platform=android&family=true
/user/123?platform=web&role=admin
或
/admin/user/123
他們相似但又不盡相同 😱
為這解決這樣的問題, GraphQL 出現了!!
簡單來說~
後端工程師把資料全放在同一個 API. 前端 (mobile 網站、 iOS / Android APP) 工程師想要資料嗎? 想要什麼資料自己拿, 全放在同一個 API 了!!!
GraphQL 有什麼優點?
- 多平台的時代, 寫一次用多次
不同平台所需的資料數量、格式都不同, client 端可以透過 GraphQL API 取想要的資料、欄位, 有效減少 request 次數! - 前、後端都能暸解 Data Schema
開發上的配合流程大概就像下圖一樣~
- 統一接口
我把資料都放在哪了, 要什麼自己拿 - 文件產出 / Docs as Code
GraphQL API 在製作/開發時會引導你把文件完成
完美達成 “程式就是文件” - 關連資料取得
資料間的連結關係也是 GraphQL 強大的特色之一
可以從 user > post > like > user > post 將資料一路連結取出
e.g. 查出使用者
某篇文章
所含的Like
, 然後這些Like
使用者
的文章
資料
- 強型別 – 統一型態
不用再擔心每支 API 各種情況不同的回傳型態, empty string, null, nil, 0 ?
graphql basic type:String
,Int
,Float
,Boolean
, andID
當然也能自訂 type 例如 PhoneNumber, Email 等… - multiple queries in one request
在特殊情況下, GraphQL 可以合併 query 送出, 不用像 rest api 一樣取使用者資料發一個 request, 取使用者文章資料再發一個 reqeust…
GraphQL 的缺點
- 開發難度增度
功能愈多, 難度愈高; 目前沒有一個推薦的 best practice… - 學習成本 / Fits Into Your Product
新、潮的技術很有趣也或許很有產生, 但除了學會它之外,
安全的置入現行產品內才是真正的挑戰. 要如何安排手上現有產品 rest api 和 graphql api 並存或取代就是個大學問了. - 注意不要變成 RESTful API
- Cache 實作問題
開放隨便取資料, 讓資料難以建立 cache…
但可以從策略面處理. - 優點即缺點的 n+1 Query 問題
graphql 的關連資料取得, 但很容易造成 db 重覆(迴圈) query 的問題
這也是最難處理的問題之一
Laravel-PHP與GraphQL API試用與實作
GraphQL 和 Laravel 要怎麼結合呢?
透過一個實驗性的 Project 來測試.
這是一個蒐集實體活動電商(手作蛋糕, 手作金飾等…), 再透過 graphql api 將資料顯示出來
🐙GitHub repo: cscolabear/rainy-to-do-app-api
(詳細說明於 GITHUB readme.md)
repo 內有兩個 branch: master 和 nuwave/lighthouse
分別使用了兩種 Laravel GraphQL 套件測試~
– branch: master 為 rebing/graphql-laravel, Laravel 上比較老牌的 graphql 套件
– branch: nuwave/lighthouse 則是未來發展看好
兩個套件各有優點~
我這邊則是使用 rebing 當做主要範例~
初期使用 playground, 方便 client / server 端做觀察、測試
一般來說 GraphQL 都是使用 POST
發出 request ~
不過為了測試方便, 目前讓 get 也能正常取得資料, 下為取得 5 筆手作行程, 指定回傳欄位為: id, 價格(price), 行程來源(source name), 分類名稱(category name) 然後 price 由高至低排序
request (get):
https://workxplay.net/rtd-app/graphql?query=query%20{products(count:5%20orderBy:{field:%22price%22%20order:DESC}){data{id%20title%20price%20source{name}%20category{name}}total%20per_page%20last_page}}
response:
{"data":{"products":{"data":[{"id":238,"title":"Hananeco \u82b1\u8c93\u86cb\u7cd5 - \u97d3\u5f0f\u64e0\u82b1 \u2027 \u9910\u684c\u4e0a\u7684\u82b1\u6d77\u7cfb\u5217","price":3000,"source":{"name":"niceday"},"category":{"name":"\u73a9\u6a02\u5eda\u623f"}},{"id":237,"title":"Miss J Baking Studio - \u4f3c\u82b1\u93e1\u9762\u86cb\u7cd5","price":3000,"source":{"name":"niceday"},"category":{"name":"\u73a9\u6a02\u5eda\u623f"}},{"id":24,"title":"\u3010\u65b0\u5317\u798f\u9686\u3011\u73a9\u7ffb\u4eca\u590f\uff01\u514d\u88dd\u5099\u9732\u71df + SUP","price":3000,"source":{"name":"niceday"},"category":{"name":"\u611b\u4e0a\u6236\u5916"}},{"id":163,"title":"\u7368\u4e00\u7121\u4e8c\u91d1\u5de5\u9ad4\u9a57\uff01\u89aa\u624b\u6253\u9020\u9ad8\u8cea\u611f\u6212\u6307","price":2980,"source":{"name":"niceday"},"category":{"name":"\u85dd\u6587\u624b\u4f5c"}},{"id":162,"title":"\u9ad4\u9a57\u50b3\u7d71\u91d1\u5de5\u7684\u624b\u4f5c\u6eab\u5ea6 - \u6572\u4e00\u53ea\u9ad8\u8cea\u611f\u624b\u74b0","price":2980,"source":{"name":"niceday"},"category":{"name":"\u85dd\u6587\u624b\u4f5c"}}],"total":248,"per_page":5,"last_page":50}}}
簡單的順序為~
– 安裝 rebing/graphql-laravel 套件, 並記得 vendor:publish
– 建立 GraphQL/Query – 核心 query resolve 的部份, 定義 query argument
– 建立 GraphQL/Type – 定義欄位 type
– config/graphql.php – 開放 schema query 入口, 定義欄位 type 對應到的 GraphQL/Type
承上! 最好先暸解 graphql 內 schema, type 至 query 間的關係
ref. https://graphql.org/learn/schema/
總結/結論
最初透過 restful 和 GraphQL API 並行的方式將 GraphQL 帶入~
可以先從小功能、新功能開始帶入
並不需要把 restful api 廢除
重要的是挑選適合、舒服的方法
延伸 / 說明 / 參考
- GraphQL 入門: 簡介 X 範例 X 優缺點: https://ithelp.ithome.com.tw/articles/10200678
這篇說明了Graph
的意思 - GraphQL 官方: https://graphql.org
首頁簡單說明幾個簡單好懂的範例 - Building a GraphQL Server with Laravel – https://morioh.com/p/827e8304f597/building-a-graphql-server-with-laravel
使用 Laravel Lighthouse 建製 GraphQL 教學