2017-03-17 17 views
4

我讀了GraphQL規範,找不到一種方法來避免1 + N * number_of_nested調用,我錯過了什麼嗎?GraphQL和嵌套資源會造成不必要的調用?

即查詢具有嵌套訂單和地址的類型客戶端,如果有10個客戶端,它將爲每個客戶端調用10個客戶端+10個調用。每個客戶端調用+10個調用.addresses。

有沒有辦法避免這種情況?並不是說緩存UUID的東西是相同的,這些都是不同的值,如果你將GraphQL指向一個可以進行連接的數據庫,那將是非常糟糕的,因爲你可以對任意數量的客戶端進行3次查詢。

我問這個,是因爲我想將GraphQL與一個可以高效地獲取嵌套資源的API集成,並且如果在解決這個問題之前有辦法解決整個圖表會很好,試圖將一些嵌套的東西放入只需一個電話。

或者我弄錯了,GraphQL只能用於微服務?

回答

1

這是GraphQL的「解析器體系結構」的一個難點。您必須通過在每個解析器中執行大量I/O操作來避免產生大量網絡延遲。首先,使用SQL DBMS的應用程序通常會遇到N + 1問題。你需要使用一些批處理和/或緩存技術來解決這個問題。

如果您在服務器上使用Node.js的,我有兩個工具推薦:

  • DataLoader - 爲配料解析器爲每個字段和緩存個人記錄的數據庫無關的工具。

  • Join Monster - SQL定製的工具,可讀取每個查詢和您的模式,併爲您編譯SQL查詢。它利用JOIN和DataLoader風格的批處理在少數(或單個)SQL查詢中從表中獲取數據。

+0

謝謝,安迪!也許我不會使用節點,也許是python或rust,但是知道它可能來自GraphQL的體系結構,我將從那裏開始並嘗試構建一個解決方案。 –

1

我認爲,你所談論的是將GraphQL與SQL數據庫後端結合使用。標準本身是數據庫不可知的,它不關心,你將如何解決代碼中可能的N + 1 SELECT問題。話雖這麼說,GraphQL服務器的特定服務器端實現引進緩解這一問題的許多不同的方式:

  • 據我所知,Ruby實現能夠利用活動記錄和寶石,如bullet應用水平配料已執行的數據庫調用。
  • JavaScript的實現可能會利用DataLoader庫,它們具有類似的將批量執行的許諾序列集合在一起的技術。你可以在行動here看到它。
  • Elixir和Python實現具有關於已執行子查詢的運行時信息的概念,可用於確定哪些數據將進一步用於執行GraphQL查詢,並可能預取它。
  • F#實現類似於Elixir,但是插件本身可以執行執行樹的實時分析以更好地描述哪些字段可能在代碼中使用,從而允許從數據庫模型中更輕鬆地拆分GraphQL域模型。
  • 許多實現(即PostGraph)將底層數據庫模型直接綁定到GraphQL模式。在這種情況下,GQL查詢通常會直接轉換爲數據庫查詢語言。
+0

這不僅適用於SQL後端,如果您有一個可以在一個請求中獲取數據的API,那麼執行多個操作會有點不好。 正如我看到javascript和python實現都有一個緩存,它只能解決已經看到的對象,比如用戶 - >朋友,朋友也是用戶實例,如果你做了很多嵌套,它肯定會解決問題。 –