Categories
程式開發

GraphQL:API的未來


當談起 API 設計時,人們首先會想到 REST API,它是 Representational State Transfer 的縮寫。 REST API 是標準化的工具,它通過 URL 的方式從服務器上獲取數據。

世紀交替之際,客戶端應用程序還是相對簡單的。那時,REST 已經開發出來了,並且適時地成為了許多客戶端應用程序的絕佳選擇。

這個 API 的提出在當時是革命性的,因為它提出了重要的 API 設計概念,比如無狀態服務器和對資源的結構化訪問。

隨著 API 設計越來越複雜,並且越來越多地依賴數據驅動,API 設計的好壞需要看以下幾個關鍵的評估點:

  • 隨著人們對移動端的使用率上升,需要更高效的數據加載方式;

  • 當要開發出能夠滿足各種客戶需求的 API 時,REST 的方式略顯不足;

  • 人們期待更快的特性開發。

解決 REST 的短板

IBM,推特、沃爾瑪實驗室、紐約時報、Intuit、Coursera 是最先一批從 RESTful API 轉移到 GraphQL API 上去的公司,它們希望僅在公司內部使用新的 API,這些公司宣稱這次 API 的轉型非常成功。

像 AWS、Yelp、GitHub、Facebook 和 Shopify 這樣的公司則更進一步,因為它們將 RESTful 轉移到 GraphQL API 上,不僅是為了在公司內部使用,而且還對外使用。

但是,你了解 GraphQL 嗎?

簡單來說,GraphQL 是一個開源的查詢語言和協議 API。你可以把 GraphQL 想像成 SQL,只是把數據庫換成 API。

GraphQL API 是基於 REST 架構的現代化替代者。不同於 REST,GraphQL 允許客戶端根據其需要請求特定的部分數據,這與請求固定數據結構的方式不同。

為什麼要大肆宣傳 GraphQL?

GraphQL 真的有什麼實用價值嗎,它會成為 API 領域的弄潮兒嗎?

有趣的是,本文目前提到的這些公司都有如下共同點:

  • 它們都有幾個移動客戶端;

  • 它們都計劃轉到微服務架構上,或者已經在使用微服務架構了;

  • 它們對 RESTful API 的依賴成倍增加,這種依賴性變得更加複雜了;

  • 它們正在尋找方法移除對它們客戶端團隊的依賴,而轉向依賴 API 團隊;

  • 它們看重開發者的經驗,並且重視優秀的 API 文檔。

正如 GitHub 工程師們做出的正確解讀:“在前端和後端使用 GraphQL 消除了我們發布的內容和你可以消費的內容之間的差距。我們真的很期待同時發布更多類似內容。

GraphQL 是 API 開發領域向前邁進的重要一步。類型安全、內省、文檔生成和可預測響應對平台的維護者和平台的使用者都有好處。

“我們期待著我們基於 GraphQL 平台的新紀元,我們也希望你也是滿懷著這樣的期待!”

GraphQL 基礎知識

GraphQL 服務器會給客戶端下發一套預定義的模式。這個基本上是可以從服務器上檢索到的模型數據,而這個預定義的模式作為服務器和客戶端之間的連接器,它定義了獲取信息的過程。

GraphQL 模式的基本元素是用 SDL(Schema Definition Language:模式定義語言)寫的,它闡明了所有能向那台特定服務器請求到的對像類型,包括這些對像要處理的各個字段。

客戶端能向服務器請求到什麼類型的數據,以及這些數據類型之間的關係等,這些查詢都是由這個模式定義的。

實際上,GraphQL 模式是可以不斷開發的,並且可以圍繞這個模式採用任何編程語言來創建出接口。

為了確保服務器能夠響應客戶端發起的查詢,客戶端可以在本地根據這個預定義模式來驗證其查詢的正確性。你可以根據 GraphQL 的查詢結構(這個結構和查詢結果非常相似)來預測輸出。

這樣還能避免非預期的意外情況發生,例如結構不正確或者數據無法獲取等。

當 GraphQL 操作到達後端應用時,後端將根據完整的模式進行解析。只有這樣,前端應用程序的數據才能被完全準確地解析。

GraphQL 操作

在 GraphQL 開發環境中,主要有 3 種操作。它們是:

  • 查詢:用於讀取數據;

  • 數據修改:用於寫入數據;

  • 訂閱消息:用於自動接收實時數據。

開發者對 GraphQL 所採用的客戶端驅動的方法非常感興趣。這僅僅是因為 GraphQL 做瞭如下的改進:發出一次查詢請求後,只用接收所需要的數據,而不是完整數據集。

在數據控制流被移交到客戶端這邊的 GraphQL 時,請求發出後,其返回的數據類型就已經確定了。

另一方面,REST 還遇到了“過度抓取數據”的問題。服務器為每項資源都定義了可用的數據。

即使只需要部分數據,客戶端都不得不請求資源庫中的整套信息,這需要反復進行網絡請求。

與 REST 比起來,GraphQL 的優勢

GraphQL 和 REST 都是一種規範,是用來構建和使用 API 的規範。這兩種技術常用的特性是,當它們通過發送請求來檢索資源時,都能返回所請求的 JSON 數據。

另外,它們都能通過 HTTP 進行操作。此外,REST 和 GraphQL 字段的接入點或多或少都是類似的,因為它們都是作為數據調用服務器上函數的入口。

儘管它們有這麼些共同點,但是它們的概念模型也有著很大不同。 GraphQL 是基於圖來創建的,而 REST 是基於文件而創建的。

說起性能,GraphQL 要快得多,因為你可以通過選擇你感興趣的查詢字段來減少請求次數。

以下是使用了 GraphQL API(而非 REST API)之後所帶來的一些較為明顯的好處。

1. 與多系統(Multifaceted Systems)和微服務能較好匹配

GraphQL 將多個系統集成到 API 中,從而形成了統一的 API 接口,並且能夠將各個系統的複雜性隱藏在 API 背後。 GraphQL 服務器的任務就是從當前這些系統中獲取數據,並且將數據打包放入 GraphQL 返回的數據格式中。

許多第三方 API 和傳統的基礎設施在這些年經歷了大舉擴張,對於這樣的 API 和基礎設施,GraphQL 與多系統的匹配性尤其重要,因為匹配得不好就會帶來維護負擔。

如果系統從一個單一的後端遷移至微服務架構,把多個微服務融合進 GraphQL 模式能夠幫助微服務間更好地通信。

即使每個微服務都定義了自己的 GraphQL 模式和自己的 GraphQL 接入點,多個微服務還是可以通過單一的 GraphQL API 網關整合到一個全局模式中。

2. 通過單一的 API 調用獲取信息

如果使用 REST API,那麼開發者需要把多個接入點合併起來才能收集到所有需要的數據,因為 REST 散落分佈在多個獨立的接入點上。

GraphQL 與 REST 的主要區別就在這裡。開發者僅僅通過一個 API 調用就可以請求到所需信息,而 GraphQL 會專注於主體任務。

3. 不會存在過多或者過少獲取數據的問題

從 REST 收到的響應來看,有一個不穩定的因素,即收到的信息裡要么信息不足,要么信息冗餘,這樣就不可避免地需要再發出一次請求。而 GraphQL 就解決了這個問題,因為它只需請求一次,就能夠獲取所需的精確的數據信息。

4. 根據你的需求自定義請求格式

開發者按照 REST API 文檔描述發出請求時,只能請求一些特定的接入點、相關函數和參數等。

而另一方面,GraphQL 可以描述數據類型、字段以及它們之間的任何交互連接點。這就允許 GraphQL 開發者自定義請求格式來獲取必要的信息。

5. 即時的身份驗證和類型檢查機制

GraphQL 的自省特性能夠為開發者導航到某個數據類型,找到相應的數據模式,確保 App 採用正確的結構發出有效的請求。

雖說GraphQL 會檢查已有模式的結構正確性,但是開發者想為當前查詢添加新的字段也是可以的,開發者可以通過GraphQL IDE 做到這點,他們不用去進一步驗證數據格式的合法性,只需要開發者們為新數據結構編寫解析器即可。

6. API 文檔的自動生成

GraphQL 的文檔和 API 修改是同步進行的,因為 GraphQL 文檔和其代碼聯繫緊密。於是,代碼修改,哪怕是一個字段、一次查詢或者是數據類型的修改,也會觸發文檔的自動更新。

7. API 的進化不用考慮版本兼容性問題

REST 提供了好幾個 API 版本,它的 API 在不斷進化修改,這意味著開發者們如果不想只支持新版本的 API,那他們就得保留 API 的舊版本。

GraphQL 就省略了該步驟,開發者們不用保留 API 舊版本,因為老舊的字段可以從模式中移除,而不會在今後影響到以前已有的查詢。

這就確保了開發者可以在 GraphQL 的進化版本中連續獲取到 App 的新特性,服務端的代碼也因此變得更加干淨和容易維護。

8. 代碼分享

如果有重用的需求,那麼可以在更高的組件級別,對 GraphQL 多個查詢中使用的字段進行共享。這些所謂的片段能夠讓你訪問各種類型的數據,同時仍然遵守相同的模式字段。

9. 詳細的報錯信息

要確定什麼地方出了問題,以及需要做什麼來應對問題時,在 REST 中只要檢查 HTTP 頭的響應狀態就足夠了。

但是,在 GraphQL 中,如果在處理數據時報錯了,後端會提供一條詳細的信息,因為後端帶有解析器。這些信息會提供查詢中錯誤所在的精確位置。

10. 權限

在創建 GraphQL 模式時,可以選擇展示哪些函數和操作。和 REST 視圖功能相比,這不是好不好的問題,而是有無的差別。

所以這裡的想法是,各個視圖應當知道在特定場景中哪些東西是需要顯示的,哪些是不用顯示的。這可不是什麼輕而易舉就能做到的事情。

綜述

我們不能說 GraphQL 是要完全取代 REST,因為前者只是一個工具,而 REST 是一種架構模式。具體哪一個更合適,將取決於它們獨特的交互場景。

更多資料

原文鏈接

GraphQL: The Future of APIs