在先前的文章中,我們深入探討了 GraphQL 伺服器的內部運作,學習了 GraphQL schema 及其在執行查詢和 mutation 時的基本作用。
雖然我們了解了 GraphQL 伺服器如何使用 GraphQL 引擎執行這些操作,但我們尚未觸及實際的用戶端-伺服器通訊方面:查詢及其回應如何透過網路傳輸的問題。這就是本文的主題!
GraphQL 伺服器可以使用您偏好的任何程式語言實作。本文重點介紹 JavaScript 以及可協助您建置伺服器的可用程式庫,最值得注意的是:
express-graphql
、apollo-server
和graphql-yoga
。
透過 HTTP 提供 GraphQL 服務
GraphQL 與傳輸層無關
關於 GraphQL,需要理解的關鍵是,它實際上與透過網路傳輸資料的方式無關。這表示 GraphQL 伺服器可能可以使用 HTTP 以外的協定(例如 WebSocket 或更底層的 TCP)運作。但是,本文重點介紹目前實作 GraphQL 伺服器最常見的方式,即以 HTTP 為基礎。
Express.js 用作強大且彈性的基礎
以下章節主要介紹 Express.js 及其 middleware 概念,middleware 用於
express-graphql
和apollo-server
等 GraphQL 程式庫。如果您已熟悉 Express,可以跳到下一節。
express、hapi、koa 和 sail 在 npm trends 上的比較
Express.js 是目前最受歡迎的 JavaScript Web 框架。它以其簡潔性、彈性和效能而著稱。
開始使用您自己的 Web 伺服器所需的所有程式碼如下
使用 Node.js 執行此腳本後,您可以在瀏覽器中存取 https://127.0.0.1:3000
上的網站
您可以輕鬆地將更多端點(也稱為 路由)新增至伺服器的 API
或使用另一個 HTTP 方法,例如 POST 而不是 GET
Express 在實作伺服器方面提供了極大的彈性,讓您可以使用 middleware 的概念輕鬆新增功能。
Express 中彈性和模組化的關鍵:Middleware
Middleware 允許攔截傳入的要求並執行專用任務,同時處理要求或在傳回回應之前執行。
本質上,middleware 只是一個函式,包含三個引數
req
:來自用戶端的傳入要求res
:要傳回給用戶端的回應next
:用於調用下一個 middleware 的函式
由於 middleware 函式可以(寫入)存取傳入的要求物件以及傳出的回應物件,因此它們是一個非常強大的概念,可以根據特定目的塑造要求和回應。
Middleware 可以用於許多使用案例,例如驗證、快取、資料轉換和驗證、執行自訂業務邏輯等等。以下是一個簡單的記錄範例,它將列印接收到要求的時間
諸如 graphql-express
、apollo-server
或 graphql-yoga
等框架都利用了透過此 middleware 方法獲得的彈性,它們都以 Express 為基礎!
Express & GraphQL
憑藉我們在上一篇文章中學到的所有關於 graphql
函式和 GraphQL 執行引擎的知識,我們已經可以預見基於 Express 的 GraphQL 伺服器如何運作。
由於 Express 提供了處理 HTTP 要求所需的一切,而 GraphQL.js 提供了用於解析查詢的功能,因此我們仍然需要它們之間的橋樑。
此橋樑由 express-graphql
和 apollo-server
等程式庫提供,它們只是 Express 的 middleware 函式!
GraphQL middleware 將 HTTP 和 GraphQL.js 結合在一起
express-graphql
:Facebook 版本的 GraphQL middleware
express-graphql
是 Facebook 版本的 GraphQL middleware,可用於 Express 和 GraphQL.js。如果您查看其原始碼,您會注意到其核心功能僅在幾行程式碼中實作。
實際上,它的主要職責有兩個
- 確保可以透過 GraphQL.js 執行傳入的 POST 要求主體中包含的 GraphQL 查詢(或 mutation)。因此,它需要剖析查詢並將其轉發到
graphql
函式以執行。 - 將執行的結果附加到回應物件,以便可以將其傳回給用戶端。
使用 express-graphql
,您可以快速啟動 GraphQL 伺服器,如下所示
使用 Node.js 執行此程式碼會在
https://127.0.0.1:4000/graphql
上啟動 GraphQL 伺服器
如果您已閱讀關於 GraphQL schema 的上一篇文章,您將很好地理解第 7 到 18 行的用途:我們建置了一個 GraphQLSchema
,可以執行以下查詢
但是,此程式碼片段的新部分是整合的網路層。這次我們不是內嵌編寫查詢並使用 GraphQL.js 直接執行它(如此處所示範),而是設定伺服器以等待傳入的查詢,然後可以針對 GraphQLSchema
執行這些查詢。
您真的不需要更多東西就可以開始使用伺服器端的 GraphQL。
apollo-server
:在 Express 生態系統之外具有更好的相容性
本質上,apollo-server
與 express-graphql
非常相似,只有一些細微差異。兩者之間的主要區別在於,apollo-server
也允許與許多其他框架整合,例如 koa
和 hapi
,以及與 AWS Lambda 或 Azure Functions 等 FaaS 提供者整合。每個整合都可以透過附加套件名稱的對應後綴來安裝,例如 apollo-server-express
、apollo-server-koa
或 apollo-server-lambda
。
但是,在核心部分,它也只是一個 middleware,將 HTTP 層與 GraphQL.js 提供的 GraphQL 引擎橋接起來。以下是使用 apollo-server-express
實作的上述基於 express-graphql
的範例的等效實作
graphql-yoga
:建置 GraphQL 伺服器最簡單的方法
消除建置 GraphQL 伺服器時的阻力
即使使用 express-graphql
或 apollo-server
,也存在各種阻力點
- 需要安裝多個相依性
- 假設事先了解 Express
- 使用 GraphQL 訂閱的設定複雜
graphql-yoga
消除了這種阻力,它是一個用於建置 GraphQL 伺服器的簡單程式庫。它本質上是 Express、apollo-server
和一些其他程式庫之上的便利層,旨在提供一種快速建立 GraphQL 伺服器的方法。(可以將其視為 GraphQL 伺服器的 create-react-app。)
以下是我們已經在 express-graphql
和 apollo-server
中看到的相同 GraphQL 伺服器的外觀
請注意,可以使用 GraphQLSchema
的現成實例或使用便利 API(基於 graphql-tools
中的 makeExecutableSchema
)來實例化 GraphQLServer
,如上面的程式碼片段所示。
內建支援 GraphQL Playground、訂閱和追蹤
請注意,graphql-yoga
也內建支援 graphql-playground
。使用上面的程式碼,您可以在 https://127.0.0.1:4000
開啟 Playground
graphql-yoga
還具有簡單的 API,可用於開箱即用的 GraphQL 訂閱,它建立在 graphql-subscriptions
和 ws-subscriptions-transport
套件之上。您可以在這個簡單明瞭的範例中查看其運作方式。
為了為使用 graphql-yoga
執行的 GraphQL 操作啟用欄位級分析,它還內建支援 Apollo Tracing。
結論
在討論了基於 GraphQLSchema
和 GraphQL 引擎(例如 GraphQL.js)概念的 GraphQL 執行過程之後(在上一篇文章中),這次我們重點介紹了網路層。特別是,GraphQL 伺服器如何透過使用執行引擎處理查詢(或 mutation)來回應 HTTP 要求。
在 Node 生態系統中,Express 憑藉其簡潔性和彈性,成為目前建置 Web 伺服器最受歡迎的框架。因此,GraphQL 伺服器最常見的實作是基於 Express,最值得注意的是 express-graphql
和 apollo-server
。這兩個程式庫非常相似,只有一些細微差異,其中最重要的是 apollo-server
也與其他 Web 框架相容,例如 koa
和 hapi
。
graphql-yoga
是許多其他程式庫(例如 graphql-tools
、express
、graphql-subscriptions
和 graphql-playground
)之上的便利層,也是建置 GraphQL 伺服器最簡單的方法。
在下一篇文章中,我們將討論傳遞到您的 GraphQL 解析器中的 info
引數的內部結構。
不要錯過下一篇文章!
註冊 Prisma 電子報