使用GraphQL設計可擴展的Java API

你是否曾想過,除了 REST API 外,是否有更好的方法來為應用程式提取數據?在後端開發中,GraphQL 已經成為一個強大的替代方案,提供了一種更靈活和高效的數據提取方式。對於熟悉 Java 的開發人員來說,將 GraphQL 整合到現代後端可以打開通往可擴展和高性能 API 的大門,適用於各種用例。

本文將探討 GraphQL 和 REST 之間的主要差異,突出使用 GraphQL 進行數據提取的獨特優勢,並指導您通過實際範例在 Java 中實現 GraphQL API。

什麼是 GraphQL?

GraphQL 是用於 API 的查詢語言,以及執行這些查詢的運行時。與 REST 不同,固定端點返回預定義的數據,GraphQL 允許客戶端精確請求他們需要的數據。這種細粒度使得 GraphQL 對於複雜或數據密集型應用程式尤其高效。

GraphQL 方法的優勢:

  • 細粒度數據提取:客戶端可以查詢僅姓名和職稱,而無需檢索像部門這樣的不必要字段。
  • 嵌套查詢:在一個查詢中連同員工信息一起提取經理詳細信息。
  • 基於模式的開發:模式作為合同,使得 API 演進更容易。

什麼是 REST API?

Representational State Transfer(REST)是一種用於構建API的架構風格。它使用標準的HTTP方法如GET、POST、PUT和DELETE來執行CRUD操作。REST以其簡單性和廣泛應用而聞名。

REST的局限性:

  • 數據的過度或不足提取。
  • 需要多個端點和版本控制來應對變化。
  • 沒有內建的實時功能。

GraphQL與REST API:有何不同?

GraphQL和REST是兩種流行的構建API的方法,各有其優勢。雖然REST多年來一直是標準,但GraphQL在數據檢索和前後端團隊協作方面提供了更大的靈活性和效率。

主要區別

  • 與使用多個端點並需要版本控制進行更改的REST不同,GraphQL將數據檢索整合到一個查詢中,減少了對版本控制的需求,因為客戶端指定了數據需求。
  • 而REST使用HTTP狀態碼來指示成功或錯誤,GraphQL始終返回200 OK狀態並在響應主體中通知錯誤。
  • GraphQL還通過訂閱支持實時更新,這一點不同於REST缺乏內建的實時支持。
  • 儘管 REST 已經廣泛建立並擁有許多工具,但 GraphQL 的環境迅速增長,提供了像 GraphiQL 這樣強大的工具以便於開發。
  • 最後,雖然 REST 使用標頭進行快取,但 GraphQL 由於動態查詢需要更先進的技術,但提供了像持久查詢這樣的選項,以便有效快取。

核心 GraphQL 概念

1. 架構定義語言 (SDL)

GraphQL 擁有自己的類型系統,用於定義 API 的架構。編寫架構的語法稱為架構定義語言 (SDL)。

2. 查詢 vs. 變更 vs. 訂閱查詢

  • 查詢 用於從伺服器獲取數據。與使用多個固定端點的 REST 不同,GraphQL 使用單一端點,而客戶端在查詢中指定所需的數據,提供了靈活性。
  • 變更 用於修改伺服器上的數據,例如創建、更新或刪除數據。它們允許客戶端將更改發送到後端,對於需要寫入數據的應用程式至關重要。
  • 訂閱 通過在客戶端和伺服器之間保持穩定的連接來實現實時更新。當訂閱的事件發生時,伺服器會將更新推送到客戶端,提供持續的數據流,與遵循請求-回應循環的查詢和變更不同。

3. GraphQL 架構

它定義了可查詢或變異的資料結構,作為伺服器與用戶端之間的合約。它指定了客戶端可以存取的類型、欄位和關係。架構通常包括特殊的根類型:查詢用於檢索資料、變異用於修改資料,以及訂閱用於實時更新。這些類型共同定義了API的功能和客戶端如何與之互動。

4. 解析器:將 GraphQL 查詢映射到資料

解析器是處理在 GraphQL 伺服器中擷取資料邏輯的函數。架構中的每個欄位都連結到一個解析器,該解析器決定如何檢索或計算該欄位的資料。當執行查詢時,伺服器會為請求的欄位調用適當的解析器。解析器可以返回純量或物件,如果返回物件則繼續執行子欄位,如果返回純量則完成。如果返回 null,執行將停止。解析器對於將 GraphQL 查詢映射到實際資料來源至關重要。

在 Java 中使用 GraphQL 的好處

  1. 精確的資料擷取:僅查詢所需的資料,確保可預測且高效的結果。
  2. 單一請求獲取多個資源:在一個查詢中檢索相關資料,減少多個 API 呼叫。
  3. 類型系統:按類型和欄位組織 API,確保查詢有效且錯誤清晰。
  4. 開發人員工具:使用諸如 GraphiQL 之類的工具增強生產力,使用類型定義進行更好的查詢構建和調試。
  5. 無版本演進:添加或棄用字段而不破壞現有查詢,使API易於維護。
  6. 靈活的數據集成:創建一個統一的API,覆蓋現有數據和代碼,與各種存儲引擎和語言兼容。

在Java中設置GraphQL API

實際示例:用戶和訂單

假設您正在為一家大型組織構建員工目錄API。目標是允許客戶查詢員工姓名、職稱、部門,甚至他們的報告層級等詳細信息。

1. 設置項目

使用Spring Tool Suite創建一個新的Spring Boot項目,或者前往Spring Initialiser。然後,在pom.xml文件中添加這些依賴項:

XML

 

2. 創建您的實體

創建Java實體(例如,UserOrder),以表示將通過GraphQL查詢或變異的數據。例如:

Java

 

3. 創建存儲庫

創建與數據庫交互的存儲庫:

Java

 

4. 創建服務類

創建服務類來處理業務邏輯:

Java

 

5. 創建 GraphQL 控制器

定義 GraphQL 控制器以處理查詢和變更:

Java

 

6. 定義您的 GraphQL 架構

src/main/resources 目錄中創建一個 schema.graphqls 文件:

Plain Text

 

7. 在 application.properties 中配置 GraphQL

可選地,在 scr/main/resources/application.properties 中配置 GraphQL 設置:

Properties files

 

8. 運行應用程式

使用 mvn spring-boot:run 或從您的 IDE 運行 SpringBoot 應用程式。一旦運行,您可以在 /graphiql 訪問 GraphAL 端點。

9. 使用 GraphQL 查詢進行測試

使用像 GraphiQL 或 Postman 這樣的工具測試 GraphQL API。

對於 Mutation:

Plain Text

 

輸出:

Plain Text

 

對於 Query:

Plain Text

 

輸出:

JSON

 

高級 GraphQL 功能

1. 通過 Fragments 增強重用性

片段基本上是為特定類型定義的可重用字段集。這是一個有助於改善您的 GraphQL 代碼結構和重用性的功能。

2. 使用參數化字段

在GraphQL中,字段可以接受参数,使查询更具动态性和灵活性。这些参数允许您过滤或自定义API返回的数据。

3. 使用GraphQL进行分页和排序

分页

分页在API设计中是一个棘手的话题。从高层次来看,有两种主要方法来处理它。

  • 限制-偏移:通过提供要检索的项目的索引来请求列表的特定块(实际上,您主要提供开始索引(偏移)以及要检索的项目数量(限制)。
  • 基于游标:这种分页模型稍微更高级一些。列表中的每个元素都与一个唯一ID(游标)相关联。然后,浏览列表的客户端提供起始元素的游标以及要检索的项目数量。

排序

使用GraphQL API设计,可以返回根据特定标准排序的元素列表。

使用GraphQL的挑战和考虑

  • 复杂性:管理GraphQL模式和查询对于简单的数据模型或经验不足的团队可能具有挑战性。
  • 性能问题:深度嵌套的查询如果没有经过优化,可能会给后端资源带来压力。
  • 缓存挑战:标准的基于REST的缓存策略不适用,需要定制解决方案。
  • 安全性考量:過度抓取和惡意查詢需要查詢限制和其他防護措施。
  • 混合使用:最適合複雜數據需求,通常與REST結合進行更簡單的操作。

結論

GraphQL提供了一種靈活且高效的方法來構建現代API,特別是在Java中,使其成為動態和數據密集型應用程序的理想選擇。它的單一端點架構和強類型簡化了API設計,同時確保了穩健的性能。無論您是在創建簡單的員工名錄還是複雜的分析平台,GraphQL都使開發者能輕鬆交付可擴展的解決方案。今天就開始探索GraphQL,使用Spring Boot和graphql-java等工具,以在您的下一個項目中發揮其全部潛力。

源代碼

您可以在Github上找到本教程的完整源代碼。

Source:
https://dzone.com/articles/design-scalable-java-apis-with-graphql