Why GraphQL? 6個問題
GraphQL, 是一個API的標準: specification.
對于每個新技術, 要搞清楚的6個問題:
- 1.這個技術出現的背景, 初衷, 要達到什么樣的目標或是要解決什么樣的問題.
- 2.這個技術的優勢和劣勢分別是什么, 或者說, 這個技術的trade-off是什么.
- 3.這個技術使用的場景.
- 4.技術的組成部分和關鍵點.
- 5.技術的底層原理和關鍵實作.
- 6.已有的實作和它之間的對比.
1.這個技術出現的背景, 初衷, 要達到什么樣的目標或是要解決什么樣的問題.
GraphQL是相對于REST API的另一種標準.
相對于REST回傳固定結構資料的多個endpoints, GraphQL的server只暴露一個endpoint, 由客戶端來規定想要的欄位和結構, 服務端精確回傳client要求的資料.
初衷和背景
2012年, Facebook有一個新聞類的iOS app. 隨著移動用戶增多, 網路請求有設備電量消耗, 弱網環境等問題.
這在當時是一個非常緊迫的issue, 于是他們研究出了GraphQL, 減小了需要發送的請求個數和資料傳輸量.
2015年Facebook將GraphQL開源.
類似的嘗試還有Netflix的Falcor和Coursera, 后者后來取消了自己的effort, 加入了GraphQL的陣營.
目標和要解決的問題
GraphQL思想: enables declaratative data fetching.
GraphQL要解決的問題: 優化客戶端向服務器請求資料的程序:
- 對于同樣的業務需求, REST API可能要請求多個endpoints, GraphQL可以用一個請求.
- 資料形式是客戶端定義的, 只取想要的資料, 不會取多余的資料, 減小了資料傳輸量.
- 各個前端可以訪問自己想要的資料.
- 快速開發, feature快速迭代. 升級改動時, 可能不需要后端改動.
2.這個技術的優勢和劣勢分別是什么, 或者說, 這個技術的trade-off是什么.
GraphQL的優勢
- 客戶端可以精準取到自己想要的資料, 不再多取或者少取. 多取: 取到了不需要的資料, 可能有性能, 流量問題; 少取: 需要多發請求來滿足需求.
- API有strong typed schema. 客戶端可以通過schema知道API支持什么, 包括操作, 引數, 可能的回應等. 支持introspection. schema是一個API能力的contract, 不需要再額外寫檔案, 一旦定義好了之后, 前后端可以獨立作業.
- 強型別, 利用schema, 結合build工具, 可以在編譯時期對請求進行一些檢查.
- 有助于產品快速升級迭代. 前端的改動可以不需要后端的修改.
- 富有洞察力的資料分析: 因為可以精細地知道client要讀的資料, 對資料的的使用情況可以有更深的理解. 在API改動的時候可以deprecate掉不用的資料. 也有助于后端的性能分析.
- schema stitching: 多個不同的GraphQL的endpoints可以組合成為一個.
- 社區支持好. 多種語言: https://graphql.org/code/#server-libraries; 多種客戶端: https://medium.com/open-graphql/exploring-different-graphql-clients-d1bc69de305f; 多種工具: Prisma, GraphQL Faker, GraphQL Playground, graphql-config.
GraphQL的缺點
- 可能并不適合所有型別的API. 比如認證, 授權(authentication and authorization).
- 服務器端的性能問題.
- 服務器端的Cache. 需要一個全域的id, 討論見: Caching.
- 通信的快速發展, 實作GraphQL節約的資料傳輸量可能不值一提, 優勢不明顯.
3.這個技術使用的場景.
GraphQL是一種規范, 具體實作有多種.
和傳輸層, 資料庫, 資料源型別都不相關.
GraphQL應用場景:
- 在資料庫之上.
- 和已有系統集成. 可以用來改造遺留系統, 統一介面, 隱藏實作.
- 混合前兩者, 在已有系統和資料庫之上.
理想開發場景: 根據資料, 建立好schema之后, 前后端獨立開發, 前端可以根據需要拿到想要的資料.
4.技術的組成部分和關鍵點.
Schema
Schema定義了API的能力, 是server和client之間的協議. 規定了客戶端可以請求的資料和型別.
The Schema Definition Language (SDL): Schema Definition Language.
Root Types: Query, Mutation, Subscription.
對應查詢, 更改和訂閱.
Server端
GraphQL服務器只暴露一個endpoint.
在API的設計上, 需要把資料按照Graph來想, 而不是按照endpoints來想, 更專注于描述資料.
對于Schema定義好的結構, Server端對于每個欄位實作resolver function, 進行查詢.
Server庫: https://graphql.org/code/#server-libraries
Client端
客戶端查詢, 更加自主的結構, 欄位級別的粒度.
Client庫: https://graphql.org/code/#graphql-clients
和Server庫一樣, 這些庫為我們封裝了一些樣板代碼, 簡化方便了我們的開發.
5.技術的底層原理和關鍵實作.
Server端實作
- schema的定義. -> structure.
- resolver function形式的具體實作. -> behaviour.
queries/mutations都包含一個欄位集合.
在server上, 每個欄位都有一個resolver function, 用來讀取相應欄位的資料.
Server上執行的機制:
The query is traversed field by field, executing “resolvers” for each field.
廣度優先. 按層級進行.
為了改善效率, JavaScript有dataloader, 把resolver的呼叫批處理, 減少重復呼叫.
Client端實作
客戶端實際上發送的是POST請求, GraphQL的query作為JSON payload的欄位.
可以用curl命令模擬得到相同的效果, 見:
https://graphql.org/graphql-js/graphql-clients/
introspection query可能是唯一的GET請求.
6.已有的實作和它之間的對比.
REST的好點子: stateless servers, structured access to resources.
REST的缺點: 快速變化的客戶端需求可能和REST的靜態屬性不合.
REST:
- 業務資料不同, 可能需要client向server發送多個請求.
- 請求中可能包含多余資料. old client也會收到新增的資料.
- 弱型別.
- 錯誤回傳不同的狀態碼.
- API升級需要提供不同的版本號.
GraphQL更加靈活和有效率.
- 單個請求.
- 不包含多余資料.
- 強型別.
- 錯誤回傳是在回應中的"errors"欄位, 包含錯誤list, 每個錯誤有"message"欄位.
- API升級不需要版本號. 新增資料和型別不會影響以前的查詢.
REST和GraphQL兩者可以共存.
參考
- GraphQL官網
- GraphQL Introduction
- The Fullstack Tutorial for GraphQL
- Top 5 Reasons to Use GraphQL
- graphql concepts
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/262451.html
標籤:其他
