Netflix 開源用于 Spring Boot的 GraphQL 服務(wù)框架DGS
作者 | Netflix 技術(shù)博客,策劃 | 田曉旭 文章來源: 架構(gòu)頭條
Netflix 公司著力開發(fā)的 Domain Graph Service(DGS)框架現(xiàn)已正式成為開源項目。DGS 框架簡化了針對獨立與聯(lián)合 GraphQL 服務(wù)的 GraphQL 實現(xiàn)。而在高強度的現(xiàn)實錘煉之后,這套框架也變得愈發(fā)穩(wěn)定強健。
通過將項目開源,我們希望為 Java 及 GraphQL 社區(qū)做出貢獻,同時與各位使用框架、增強框架的參與者們攜手合作。
DGS 框架的主要功能包括:
-
基于注釋的 Spring Boot 編程模型
-
用于將查詢測試編寫為單元測試的測試框架
-
Gradle 代碼生成插件,可通過 GraphQLschema 創(chuàng)建 Java/Kotlin 類型
-
與 GraphQLFederation 輕松集成
-
與 Spring Security 相集成
-
GraphQL 訂閱 (WebSockets 與 SSE)
-
文件上傳
-
錯誤處理
-
自動支持 interface/union 類型
-
提供面向 Java 的 GraphQL 客戶端
-
可插拔 Instrumentation
2019 年春季,Netflix 公司開啟了這段偉大的聯(lián)合 GraphQL 架構(gòu)探索之旅。向這種新型聯(lián)合架構(gòu)的過渡,意味著我們的眾多后端團隊需要在 Java 生態(tài)系統(tǒng)中使用 GraphQL。之前我們曾發(fā)表博文,提到 Netflix 已經(jīng)在 Spring Boot 上實現(xiàn)了后端開發(fā)標準化。因此,要讓這套聯(lián)合架構(gòu)取得成功,我們需要在 Spring Boot 中為 GraphQL 提供良好的開發(fā)者體驗。
為此,我們在 Spring Boot 上創(chuàng)建起自有框架,其中用到 graphql-java 庫。這套框架最初只供內(nèi)部使用,主要強調(diào)與 Netflix 生態(tài)系統(tǒng)相集成以實現(xiàn)跟蹤、日志記錄及指標整理等。但在此期間,我們也一直強調(diào)應(yīng)該將框架進行適當(dāng)模塊化。很明顯,我們構(gòu)建的大多數(shù)框架并不特定于 Netflix,主要用于提供一種更簡便的 GraphQL 服務(wù)(獨立與聯(lián)合)構(gòu)建方法。
Schema 代表的是 GraphQLAPI。正是 schema 的存在,讓 GraphQL 如何強大、又與 REST 有所不同。GraphQL 模式會根據(jù)查詢及變異操作,配合相關(guān)類型與字段以描述 API。API 用戶可以精確指定希望在查詢中檢索的字段,借此極大提高 GraphQLAPI 的靈活性。
GraphQL 分為兩種不同方法:schema 優(yōu)先與代碼優(yōu)先。通過選擇 schema 優(yōu)先開發(fā)方法,您可以使用 GraphQLSchema 語言手動定義 API 的 schema。服務(wù)中的代碼將僅用于實現(xiàn)此 schema。
使用代碼優(yōu)先開發(fā),您無需使用任何 schema 文件。相反,由運行時根據(jù)代碼中的定義生成 schema。
我們的框架同時支持 schema 優(yōu)先與代碼優(yōu)先這兩種方法。在 Netflix,我們明確傾向使用 schema 優(yōu)化的開發(fā)方式,理由包括:
-
Schema 設(shè)計是開發(fā)者體驗中的重中之重。
-
能夠為工具提供一種更簡便的 schema 使用方法。
-
由 schema 差異能夠讓變更引發(fā)的向下不兼容性更明顯。在聯(lián)合 GraphQL 架構(gòu)下,向下兼容性無疑至關(guān)重要。
盡管使用代碼生成 schema 一般更有速度優(yōu)勢,但我們愿意投入更多時間來建立起易于理解的 schema 協(xié)作模式設(shè)計,希望借此建立更出色的 API。
3框架實操此框架的核心圍繞 Spring Boot 開發(fā)者所熟悉的、基于注釋的編程模型進行。項目網(wǎng)站上提供全面的說明文檔,下面我們將通過一項示例,向大家展示如何輕松使用這套框架。
讓我們先從簡單的 schema 開始。
要實現(xiàn)此 API,我們需要編寫一個數(shù)據(jù)提取程序。
其中的 Show 類型是一個簡單 POJO,通常由 Gradle 的 DGS 代碼生成插件所生成。使用 @DgsData 注釋方法,即可為字段實現(xiàn)數(shù)據(jù)獲取程序。請注意,我們不需要為每個字段獲取數(shù)據(jù);這里可以直接返回 Java 對象,由框架完成其余工作。這套框架還具有多種其他便捷性優(yōu)勢,例如本示例中使用的 @InputArgument 注釋。
此代碼足以讓 GraphQL 端點保持運行。接下來,只需要啟動 Spring Boot 應(yīng)用程序,即可使用 /graphql 端點以及 /graphiql 上開箱即用的 GraphiQL 查詢編輯器。示例中的代碼簡單明了,而且即使是使用聯(lián)合類型,使用 @Secured 或者使用擴展點添加指標與跟蹤,代碼內(nèi)容也不會有太大區(qū)別。總之,框架本身將負責(zé)解決所有繁重的工作內(nèi)容。
本框架的另一大關(guān)鍵,在于支持輕量級查詢測試。通過測試流程,您無需使用 HTTP 端點即可執(zhí)行查詢。測試本身的使用感受與普通 Junit 測試基本一致。
關(guān)于這套框架的完整說明文檔,請參見 DGS框架 GitHub repo。
https://netflix.github.io/dgs/
4對接 GraphQL 服務(wù)器生態(tài)系統(tǒng)那么,DGS 框架要如何全面適應(yīng)現(xiàn)有 GraphQL 生態(tài)系統(tǒng)?當(dāng)前生態(tài)系統(tǒng)涵蓋服務(wù)器、客戶端、聯(lián)合網(wǎng)關(guān)以及工具,可幫助您進行查詢測試、schema 管理、代碼生成等。在使用 JVM 構(gòu)建 GraphQL 服務(wù)器時,生態(tài)系統(tǒng)也為我們提供大量 schema 優(yōu)先庫與代碼優(yōu)先庫選項。
graphql-kotlin 是一套面向 Kotlin 語言的高人氣代碼優(yōu)先庫。graphql-java 則是在 Java 當(dāng)中實現(xiàn) schema 優(yōu)先 GraphQLAPI 的首選方案,但在設(shè)計上屬于低級庫。graphql-java-kickstart 入門程序由一組用于實現(xiàn) GraphQL 服務(wù)的庫組成,并在 graphql-java 的基礎(chǔ)之上提供 graphql-java-tools 與 graphql-java-servlet。
無論您使用 Java 還是 Kotlin,我們的框架都能提供在 Spring Boot 中構(gòu)建 GraphQL 服務(wù)的簡便方法。此框架還可分別用于構(gòu)建獨立服務(wù)與聯(lián)合 GraphQL。
5聯(lián)合DGS 框架能夠以便捷的方法實現(xiàn)聯(lián)合 GraphQL 服務(wù)。聯(lián)合機制,意味著各服務(wù)能夠共享網(wǎng)關(guān)所公開的統(tǒng)一圖。通常,服務(wù)使用由 Apollo 聯(lián)合規(guī)范所定義的 @extends 指令,借此在統(tǒng)一 schema 中實現(xiàn)服務(wù)共享與類型擴展。這也是一種將大規(guī)模單體 GraphQLschema 拆分成多個微服務(wù)的有效方法。
對于傳入的查詢,聯(lián)合網(wǎng)關(guān)能夠構(gòu)建查詢計劃以調(diào)用所需的服務(wù),借此完成查詢操作。每項服務(wù)又需要能夠響應(yīng) _entities 查詢,以便在一定程度上完成對所擁有數(shù)據(jù)的查詢。
下面以 Reviews(評論)服務(wù)為例,了解如何在 reviews 字段擴展之前定義的 Show 類型:
帶有 Shows 與 Reviews DGS 的聯(lián)合 GraphQL 架構(gòu)
在此 schema 下,Reviews DGS 需要為聯(lián)合 Show 類型實現(xiàn)一個解析器,并在其中填充 reviews 字段。大家可以使用 @DgsEntityFetcher 注釋輕松完成此項操作,如下所示:
此框架還使您可以輕松通過代碼生成功能對聯(lián)合查詢加以測試,借此為基于 schema 的服務(wù)生成 _entities 查詢。
6框架架構(gòu)從開發(fā)之初,我們就專注于實現(xiàn)代碼模塊化。這是一項重要的設(shè)計選擇,能夠在不影響我們內(nèi)部團隊的前提下開源大部分框架。但我們無法使用 Java 9 中引入了模塊系統(tǒng),因為 Netflix 內(nèi)部的多數(shù)應(yīng)用程序仍在使用 java 8。但借助 Gradleapi 與 implementation 模塊,我們得以創(chuàng)建起簡單整潔的模塊結(jié)構(gòu)。在 Netflix,我們將大量 Spring Boot 擴展與自有基礎(chǔ)設(shè)施集成起來。我們將這套體系稱為 Spring Boot Netflix。DGS 框架基于標準的開源 Spring Boot 構(gòu)建而成。最重要的是,我們也有部分模塊與特定基礎(chǔ)設(shè)施相集成,且僅使用核心框架提供的擴展點。
下圖所示,為各模塊如何實現(xiàn)裝配集成:
包含 Netflix 與 OSS 模塊的 DGS 框架
7分布式跟蹤與指標在 Netflix,我們擁有一夶包含跟蹤、指標、分布式日志記錄以及身份驗證 / 授權(quán)等功能的自定義基礎(chǔ)設(shè)施。如前所述,DGS 框架能夠與這套基礎(chǔ)設(shè)施集成起來,提供開箱即用的無縫化體驗。雖然這些功能并未開源,但仍可以輕松被添加到框架當(dāng)中。
該框架還支持 graphql-java 庫中定義的 Instrumentation 類。通過實現(xiàn) Instrumentation 接口并通過 @Component 進行注釋,此框架可以自動拾取這些類。感興趣的朋友可以參閱說明文檔中的相關(guān)參考示例。我們也期待更多社區(qū)參與者圍繞分布式跟蹤與指標的通用模式做出貢獻。
https://netflix.github.io/dgs/advanced/instrumentation/
8立即體驗要開始使用 DGS 框架,請參閱說明文檔及教程。要為 DGS 框架做出貢獻,請在 GitHub 上查看 DGS 框架項目。我們還擁有一款 Gradle代碼生成插件,用于根據(jù) GraphQLschema 生成 Java 與 Kotlin 類型。要參與代碼生成插件的貢獻,請在 GitHub 上查看此項目。
9團隊成果DGS 框架在 Netflix 中獲得的成功,離不開各參與團隊的共同努力。我們要感謝來自 BFG 團隊的各位同事,他們與我們共同完成了這段奇妙的探索之旅。最后,我們還要感謝各位用戶給出的及時反饋與代碼貢獻。
原文鏈接:https://netflixtechblog.com/open-sourcing-the-netflix-domain-graph-service-framework-graphql-for-spring-boot-92b9dcecda18?gi=978ff7b803d3
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!