優化細粒度GraphQL存取控制與查詢效能

GraphQL既是一種API查詢語言,也是一個用於執行這些查詢的運行時,可與您現有的數據配合使用。它提供了對API中可用數據的全面且清晰的描述,允許客戶端精確請求所需的數據,避免過多數據,促進API隨時間的演變,並支持強大的開發者工具。

GraphQL訪問控制和查詢優化

訪問控制

授權是一組規則或業務邏輯,用於確定用戶、會話或上下文是否具有訪問控制列表(ACL),以執行特定操作或查看特定數據。

此類行為應在業務邏輯層強制執行。雖然將授權邏輯直接放置在GraphQL層可能很誘人,但通常更適合在其他地方處理。

查詢優化

優化GraphQL查詢涉及各種技術,例如最小化不必要的數據抓取和處理,以改善響應時間並減少服務器負載。這導致應用程序更高效,提供更好的用戶體驗,增強用戶參與度和留存率,並提高服務器可擴展性。

優化GraphQL查詢的方法

  • N+1(批量加載)
  • 過度抓取和抓取不足
  • 緩存以減少延遲
  • 分頁

增強GraphQL訪問控制和GraphQL查詢優化

授權引擎使用ACL(訪問控制列表)驗證節點和字段權限,並基於權限優化GraphQL查詢。此外,N+1解析器通過合併查詢來提高性能。這種方法解決了N+1問題。 

Figure 1



演員

  • GraphQL查詢:客戶端發送到GraphQL服務器以獲取特定數據的請求。
  • GraphQL引擎:指允許您執行GraphQL查詢的服務。
  • 授權引擎:使用ACL驗證節點和字段的權限,並基於字段權限優化GraphQL查詢。
  • N+1解析器:減少與多個數據庫查詢相關的開銷和延遲,提高性能和效率。

Figure 2

Figure 3

增強訪問控制

現有實現

假設一個應用有產品、供應商和地址。訪問供應商和地址數據需要用戶身份驗證,這可以在解析器中輕鬆處理。

然而,供應商資料僅限於管理員用戶,且某些供應商欄位僅對特定角色可訪問。另一方面,產品是公開的,並可以通過產品所有者角色查看。執行所提到的查詢(圖3)將返回產品資料以及相關的供應商和地址資料,導致安全問題。

增強實現

節點和查詢欄位將根據用戶的權限進行驗證,並生成優化的GraphQL查詢。

Figure 3.1 (Flow Diagram)

 

Figure 4

圖4是使用Node.js在GraphQL API中實現自定義身份驗證的示例。在這段代碼中,從授權標頭中提取角色,然後與查詢一起用於驗證授權。

Figure 5

在這個例子中,我們使用來自會話或請求的用戶角色和權限來控制對GraphQL模式中特定查詢和突變的訪問。我們已在GraphQL模式中為所有用戶定義了角色和權限規則。

此方法遞歸地檢查所有節點和欄位的角色和權限。如果節點或欄位未獲許可,則根據配置執行以下操作之一:

  • 移除節點或欄位。
  • 返回帶有錯誤消息的欄位或節點。
  • 拋出異常。

一旦GraphQL查詢經過模式驗證,此方法將返回優化的GraphQL查詢。

使用N+1增強ORM查詢優化

現有實現

這是一個影響查詢性能的技術問題。它可能會在使用物件關係映射(ORM)框架訪問數據庫的應用程序中出現。

這通常發生在應用程序需要從數據庫加載一系列相關實體時。

假設有2個產品;它需要執行1次查詢來檢索產品,以及2次額外查詢來分別為每個產品抓取供應商。

Figure 6

Figure 7

一次查詢檢索產品列表,另一個獨立查詢為每個產品抓取供應商。供應商查詢的數量等於產品的數量。

增強實現

一旦請求到達N+1解析器,N+1解析器會優化查詢,通過將其減少為對主數據的一次查詢和對相關數據的額外查詢,從而有效緩解N+1問題。

  1. 主數據查詢:一個單一的查詢,檢索應用程序所需的主數據集。
  2. 相關數據查詢:一個額外的查詢,抓取完成數據集所需的任何相關數據。

Figure 8

Figure 9: Total No. of Queries are 2 (1 for Product, 1 for Vendor)

Figure 10

在所有查詢解析器完成後,服務器以JSON格式將優化後的數據返回給客戶端。

結論

我們已經概述了實施細粒度授權機制以及增強的安全措施對於保護GraphQL API至關重要。這包括節點級別和字段級別的安全。

正如本文所描述的,當未優化的查詢導致GraphQL中過多的數據庫調用時,就會出現N+1問題。我們已經提供了一個解決方案來克服N+1問題。它減少了數據庫服務器資源的使用,從而節省成本並提高可擴展性。此外,通過增強查詢性能,這可以通過減少查詢響應時間來改善用戶體驗。

Source:
https://dzone.com/articles/optimizing-fine-grained-graphql-access-control-and-queries