2017年11月28日

GraphQL 伺服器基礎:網路層

GraphQL 伺服器的結構與實現(第二部分)。

GraphQL Server Basics

上一篇文章中,我們深入探討了 GraphQL 伺服器的內部工作原理,瞭解了GraphQL 模式以及它在執行查詢和變更操作時的基礎作用。

雖然我們學習了 GraphQL 伺服器如何使用 GraphQL 引擎執行這些操作,但我們還沒有觸及實際的客戶端-伺服器通訊方面:即查詢及其響應如何透過網路進行傳輸的問題。這就是本文要討論的內容!

GraphQL 伺服器可以用您喜歡的任何程式語言實現。本文重點關注 JavaScript 以及幫助您構建伺服器的可用庫,最著名的是:express-graphqlapollo-servergraphql-yoga

透過 HTTP 提供 GraphQL 服務

GraphQL 與傳輸層無關

關於 GraphQL,一個關鍵點是它實際上與資料在網路上的傳輸方式無關。這意味著 GraphQL 伺服器可能基於除 HTTP 以外的協議工作,例如 WebSockets 或更底層的 TCP。然而,本文重點介紹目前實現 GraphQL 伺服器最常見的方式,即基於 HTTP。

Express.js 用作強大而靈活的基礎

以下部分主要介紹 Express.js 及其在 GraphQL 庫(如 express-graphqlapollo-server)中使用的中介軟體概念。如果您已經熟悉 Express,可以跳到下一部分。

在 npm 趨勢上比較 express、hapi、koa 和 sailnpm 趨勢上比較 expresshapikoasail

Express.js 是目前最流行的 JavaScript Web 框架。它以其簡潔性、靈活性和高效能而著稱。

您只需以下程式碼即可啟動您自己的 Web 伺服器

使用 Node.js 執行此指令碼後,您可以在瀏覽器中訪問 https://:3000 網站

您可以輕鬆地為伺服器 API 新增更多端點(也稱為路由

或者使用另一種HTTP 方法,例如 POST 而不是 GET

Express 在伺服器實現方面提供了極大的靈活性,允許您使用中介軟體概念輕鬆新增功能。

Express 中實現靈活性和模組化的關鍵:中介軟體

中介軟體允許攔截傳入請求並執行特定任務,無論是在請求處理期間還是在響應返回之前。

本質上,中介軟體只是一個接收三個引數的函式

  • req:來自客戶端的傳入請求
  • res:要返回給客戶端的響應
  • next:呼叫下一個中介軟體的函式

由於中介軟體函式對傳入請求物件和傳出響應物件都具有(寫入)訪問許可權,因此它們是一個非常強大的概念,可以根據特定目的塑造請求和響應。

中介軟體可用於許多用例,例如身份驗證快取資料轉換驗證自定義業務邏輯執行等等。這是一個簡單的日誌記錄示例,它將列印接收請求的時間

透過這種中介軟體方法獲得的靈活性被諸如 graphql-expressapollo-servergraphql-yoga 等框架所利用,它們都基於 Express!

Express 與 GraphQL

結合我們在上一篇文章中瞭解到的關於 graphql 函式和 GraphQL 執行引擎的一切知識,我們已經可以預見基於 Express 的 GraphQL 伺服器如何工作了。

由於 Express 提供了處理 HTTP 請求所需的一切,而 GraphQL.js 提供瞭解析查詢的功能,我們現在所需要的就是它們之間的“粘合劑”。

這種“粘合劑”由諸如 express-graphqlapollo-server 等庫提供,它們本質上都是 Express 的中介軟體函式!

GraphQL 中介軟體將 HTTP 和 GraphQL.js 粘合在一起

express-graphql:Facebook 的 GraphQL 中介軟體版本

express-graphql 是 Facebook 的 GraphQL 中介軟體版本,可與 Express 和 GraphQL.js 一起使用。如果您檢視其原始碼,您會發現其核心功能僅用幾行程式碼就實現了。

實際上,它的主要職責是雙重的

  • 確保傳入 POST 請求正文中包含的 GraphQL 查詢(或變更)可以由 GraphQL.js 執行。因此,它需要解析出查詢並將其轉發給 graphql 函式進行執行。
  • 將執行結果附加到響應物件,以便將其返回給客戶端。

使用 express-graphql,您可以快速啟動 GraphQL 伺服器,如下所示

使用 Node.js 執行此程式碼會在 https://:4000/graphql 啟動一個 GraphQL 伺服器

如果您閱讀了關於 GraphQL 模式的上一篇文章,您就會非常清楚第 7 到 18 行的用途:我們構建了一個可以執行以下查詢的 GraphQLSchema

然而,此程式碼片段的新部分是整合的網路層。這次我們不是直接內聯編寫查詢並用 GraphQL.js 執行它(如這裡所示),而是設定伺服器等待傳入查詢,然後針對 GraphQLSchema 執行這些查詢。

要在伺服器端開始使用 GraphQL,您確實不需要更多的東西了。

apollo-server:在 Express 生態系統之外具有更好的相容性

本質上,apollo-serverexpress-graphql 非常相似,只有一些微小差異。兩者之間的主要區別在於,apollo-server 還支援與許多其他框架整合,例如 koahapi,以及 AWS Lambda 或 Azure Functions 等 FaaS 提供商。每個整合都可以透過在包名後附加相應的字尾來安裝,例如 apollo-server-expressapollo-server-koaapollo-server-lambda

然而,其核心也僅僅是一箇中間件,用於連線 HTTP 層和 GraphQL.js 提供的 GraphQL 引擎。以下是上述基於 express-graphql 示例的等效實現,使用 apollo-server-express

graphql-yoga:構建 GraphQL 伺服器最簡單的方式

消除構建 GraphQL 伺服器時的摩擦

即使在使用 express-graphqlapollo-server 時,也存在各種摩擦點

  • 需要安裝多個依賴
  • 假設您已具備 Express 知識
  • 使用 GraphQL 訂閱的複雜設定

這種摩擦透過 graphql-yoga 得以消除,它是一個用於構建 GraphQL 伺服器的簡單庫。它本質上是 Express、apollo-server 和一些其他庫之上的便利層,提供了一種快速建立 GraphQL 伺服器的方式。(可以將其視為 GraphQL 伺服器的 create-react-app。)

以下是與 express-graphqlapollo-server 相同的 GraphQL 伺服器示例:

請注意,GraphQLServer 可以使用現成的 GraphQLSchema 例項例項化,也可以使用便捷 API(基於 graphql-tools 中的 makeExecutableSchema)例項化,如上面的程式碼片段所示。

內建支援 GraphQL Playground、訂閱和追蹤

請注意,graphql-yoga 還內建支援 graphql-playground。使用上述程式碼,您可以在 https://:4000 開啟 Playground。

graphql-yoga 還開箱即用地提供了用於 GraphQL 訂閱的簡單 API,它基於 graphql-subscriptionsws-subscriptions-transport 包構建。您可以在這個簡單示例中檢視它是如何工作的。

為了對使用 graphql-yoga 執行的 GraphQL 操作啟用欄位級分析,還內建支援 Apollo Tracing

總結

上一篇文章中討論了基於 GraphQLSchema 和 GraphQL 引擎(例如 GraphQL.js)的概念的 GraphQL 執行過程之後,本次我們重點關注網路層。特別是,GraphQL 伺服器如何透過執行引擎處理查詢(或變更)來響應 HTTP 請求。

在 Node 生態系統中,Express 以其簡潔性和靈活性,是目前最流行的構建 Web 伺服器的框架。因此,最常見的 GraphQL 伺服器實現都基於 Express,最著名的是 express-graphqlapollo-server。這兩個庫非常相似,只有一些細微差異,其中最重要的一點是 apollo-server 也相容其他 Web 框架,例如 koahapi

graphql-yoga 是在許多其他庫(例如 graphql-toolsexpressgraphql-subscriptionsgraphql-playground)之上提供的一個便捷層,是構建 GraphQL 伺服器最簡單的方式。

在下一篇文章中,我們將討論傳入 GraphQL 解析器中的 info 引數的內部機制。

不要錯過下一篇文章!

訂閱 Prisma 新聞通訊

© . This site is unofficial and not affiliated with Prisma Data, Inc.