每日最新頭條.有趣資訊

分分鐘將 REST 轉換為 GraphQL

作者丨Noorain Panjwani

譯者丨張衛濱

策劃 | 萬佳

這個指南教你在不修改任何代碼的情況下,完成從 REST 到 GraphQL 的遷移。這樣,GraphQL 就能讓你的 REST 真正休息一下了!

從 REST 到 GraphQL

GraphQL 的支持者在宣傳推廣 GraphQL 方面已經做得非常好了。出於對他們努力的尊重,我就不再深入介紹細節,只是稍微總結一下:

GraphQL 允許我們在單個請求中獲取多個資源;

通過精確描述所需數據,GraphQL 解決了 REST 過度抓取數據的問題;

GraphQL 借助在一個請求中獲取相關的數據,解決了前端 N+1 查詢的問題。

本指南中,我會介紹大多數倡導 GraphQL 的人所忽略的一個點,就是“我們在 REST 上有了巨大投入”。這意味著:

我們大多數的服務都是基於 REST 的;

我們更願意編寫 REST 服務;

我們希望支持使用 REST API 的現有客戶端。

雖然有許多文章幫我們從 REST 遷移到 GraphQL,但這些做法都迫使我們更改現有的代碼庫或在 REST 服務前面編寫新的代碼庫。

但是,稍等一下……

如果它還能運行,就別去碰它。

這難道不是編程的第一規則嗎?

遷移可能非常痛苦,尤其是面對巨大的代碼庫時,更會令人望而生畏。隨時存在將已有功能破壞掉的可能性。

我們為什麽不能繼續保持 REST 呢?我們天性懶惰,都喜歡用簡單的技巧和容易的解決方案。

如果有一種方式,讓我們原樣保持 REST 服務,且無需任何代碼變更就能在其之上實現一個 GraphQL 層,那會怎樣?聽起來很神奇, Space Cloud 就能幫我們實現這一切

Space Cloud 是什麽?

簡而言之,Space Cloud 是一個開源的 Web 伺服器,它能在數據庫和微服務之上即時提供 GraphQL 和 REST API。

Space Cloud 最酷的一點在於,所有 API 都是實時的。我們可以選擇訂閱數據庫的變更。在實現實時應用時,該功能非常便利。

本指南中,我們會用 Space Cloud 的 remote service 模塊將 REST 服務遷移成 GraphQL。

架構

基於 REST 之上的 GraphQL 架構最終如下圖所示:

我們的應用將會發起對 Space Cloud 的 GraphQL 查詢,該請求又會訪問伺服器上的 REST 端點。在該場景中,Space Cloud 會作為 GraphQL 代理或 API 網關。

你可能注意到,Space Cloud 是一個單獨的 GraphQL 層,位於 REST 服務之上。這種方式的優點在於 REST 服務依然能夠保持原樣,已有的客戶端可以直接使用它們。這樣,從 REST 服務遷移至 GraphQL 不會破壞舊的客戶端。

接下來,讓我們開始。

我們將要構建什麽?

本指南中,我們將會構建一個簡單的算數服務,它包含如下端點:

求和計算端點:POST /adder

翻倍計算端點:GET /doubler/:num

求和計算端點將會返回兩個數的和,這兩個數是通過請求的 body 獲取到的。翻倍計算端點將會對其接收到的值翻倍,初始值是通過 URL 路徑參數獲取到的。

現在,開始構建

第一步:編寫服務

現在,我們開始編寫 REST 服務。在這裡,我們使用 NodeJS 和 Express 來編寫 REST 服務。

注意:你可以使用任意語言和框架來編寫服務,只要它支持 HTTP 即可,因為這是 Space Cloud 用來與你的 REST 服務進行通信的協議。

首先,創建一個文件夾作為工作目錄。

創建 NPM 項目

安裝 Express

編寫 express

伺服器創建名為 index.js 的文件,並複製粘貼如下代碼:

可以看到,代碼非常簡單直接。我們只是使用 ExpressJS 創建了一個 HTTP 伺服器並監聽 5000 端口。

如前文所示,伺服器包含兩個端點:

求和計算端點:我們預期從 POST 的 body 中接收到兩個數字,即 num1 和 num2,接下來所做的就是返回這兩個數字的和。

翻倍計算端點:我們將通過 URL 路徑參數得到的數字乘以 2,然後返回。對於服務來講,我們做這些就足夠了。

第二步:啟動服務

要運行服務,我們只需執行如下命令即可:

我們讓 REST 服務啟動並運行了起來。接下來,啟動 Space Cloud 並通過 GraphQL 來使用 REST 服務。

第三步:下載 Space Cloud

我們需要為自己的作業系統下載 Space Cloud 二進製文件,也可以通過其源碼直接進行構建。如果從源碼構建的話,需要 go 1.13.0 或更高版本。

可以通過以下鏈接下載對應作業系統的二進製文件:

Mac

Linux

Windows

下載後,我們解壓壓縮包。

對於 Linux/Mac:unzip space-cloud.zip && chmod +x space-cloud

對於 Windows:右鍵點擊壓縮包並選擇“解壓到此處”。

為確保二進製文件的正確性,在二進製文件的解壓目錄下,運行如下命令:

對於 Linux/Mac:./space-cloud -v

對於 Windows:space-cloud.exe -v

它將會展現如下輸出:

第四步:下載 Space Cloud

要以 dev 模式啟動 Space Cloud,可以複製粘貼如下命令並點擊回車鍵:

對於 Linux/Mac:./space-cloud run --dev

對於 Windows:space-cloud.exe run --dev

在 Space Cloud 啟動時,我們會看到如下所示的輸出:

注意:--dev 標記會告訴 Space Cloud 以 dev 模式運行(所以,admin UI 不會要求輸入用戶名和密碼)。

第五步:配置 Space Cloud

我們注意到,Space Cloud 在工作目錄生成一個 config.yaml 文件。

Space Cloud 需要該文件來完成它的功能。這個文件用來加載一些信息,包括要連接的 REST 伺服器以及它們的端點。Space Cloud 有自己的 Mission Control(admin UI),借助它能夠快速完成配置。

打開 Mission Control導航至 http://localhost:4122/mission-control,可以打開 Mission Control。

注意:如果你不是在本地 Space Cloud 的話,那麽需要將 localhost 替換為實際地址。

創建項目點擊 Create a Project 按鈕,打開如下界面:

為你的項目設置一個 name。

在這裡選擇什麽數據庫無關緊要,因為我們不會用到它。

點擊 Next 創建項目。

第六步:添加遠程服務到 Space Cloud 中

導航至 Mission Control 的 Remote Services 區域。

點擊 Add first remote service 按鈕來打開如下的表單:

將服務名設置為 arithmetic,並將服務的 URL 設置為:

添加完遠程服務之後,在遠程服務的表格中,我們應該就能看到它:

點擊 Actions 列中的 Add 按鈕,將會打開服務頁面。

點擊 Add first remote endpoint 按鈕,打開如下所示表單:

為求和計算端點添加如下內容:

Name:adder

Method:POST

Path:/adder

再次點擊“Add”按鈕並添加 doubler 端點:

Name:doubler

Method:GET

Path:/doubler/

注意:現在不要擔心部分,只需要確保將 Method 設置為 GET 即可。

第七步:通過 GraphQL 來查詢 REST 服務

現在,我們添加了 REST 和兩個端點到 Space Cloud 中,接下來,我們該使用統一的 GraphQL API 對其進行查詢。

跳轉至 Explorer 區域:

嘗試在 GraphiQL explorer 中運行如下的 GraphQL 查詢:

將會看到如下所示的響應:

在得到上述 GraphQL 查詢後,Space Cloud 會向 REST 服務發送如下的請求:

Method:POST

Path:/adder

Request Body:

這意味著我們傳遞給 GraphQL 查詢的參數以 Request Body 的形式傳遞給了 REST 服務。

接下來,我們嘗試使用如下的 GraphQL 查詢來訪問 doubler 端點:

GraphQL 查詢會被 Space Cloud 翻譯成為對 REST 的調用,如下所示:

如果你還記得的話,我們添加到 Space Cloud 的 doubler 端點是這樣的:

基於該端點,Space Cloud 能夠知道它要從 GraphQL 中獲取一個參數 num,並使用它作為變量來形成路徑 /doubler/50。

成功調用後,我們會看到如下所示的響應:

額外獎勵——服務鏈

如果成功遵循這個指南的話,我們會有一個獎勵!這個 REST 到 GraphQL 的轉換為我們解鎖了一個超級強大的功能:服務鏈(Service Chaining)。

讓我們來看一個場景:

我們想要使用 the adder service 對兩個數字求和;

我們想把從 the adder service 得到的結果翻倍。

REST 方式

如果我們在客戶端代碼中使用 REST 的話,上述任務將會如下所示:

注意,我們從前端發出兩個請求,就意味著往返時間會翻倍。它會導致較慢的響應時間和較差的用戶體驗。

GraphQL 方式

現在,如果我們將客戶端從 REST 切換為使用 Space Cloud 的 GraphQL,那麽我們的請求將會如下所示:

注意,在這裡,我們隻從前端發起了一次 GraphQL 查詢到後端(Space Cloud)。而 Space Cloud 發起兩次請求到 REST 伺服器以滿足該請求。但是,這些請求(從 Space Cloud 到我們的伺服器)的往返時間是微不足道的,因為它們位於同一個網絡中。

要完成上述任務,到 Space Cloud 的 GraphQL 查詢如下所示:

請注意,我們是如何在得到 adder 服務的響應後調用 doubler 服務的,而且我們將 adder 服務的 result 以參數形式傳遞給 doubler 服務。

查詢結果將會如下所示:

可以猜到,我們得到的結果是 60,即 ((10 + 20) * 2)。

小提示:如果你想並行執行兩個不相關 REST 服務的話,我們可以在一個請求中完成,如下所示:

我把這個查詢會得到什麽響應作為作業留給讀者。

結論

首先,鼓勵一下自己,因為你完整地讀完了該指南。

通過該指南,我們學到:

從 REST 遷移到 GraphQL 不需要更改代碼。

我們不需要在 REST 和 GraphQL 之間進行非此即彼的選擇。我們可以在同一個應用程序中同時支持 REST 和 GraphQL。

借助 Space Cloud 來使用 GraphQL 會帶來網絡方面的收益,有助於減少往返時間。

除了從 REST 遷移到 GraphQL(如跨數據庫連接)之外,我們還可以用 Space Cloud 做更多事情。

點個在看少個 bug

獲得更多的PTT最新消息
按讚加入粉絲團