GraphQL 入門: Apollo Client 查詢(Batching)合併

GraphQL 入門: 簡介
GraphQL 入門: Apollo Client - 簡介
GraphQL 入門: Apollo Client - 安裝和配置選項
GraphQL 入門: Apollo Client - 鏈接到數據
GraphQL 入門: Apollo Client - 網絡層
GraphQL 入門: Apollo Client - 開發調試工具
GraphQL 入門: Apollo Client - 持久化GraphQL查詢概要
GraphQL 入門: Apollo Client - 存儲API
GraphQL 入門: Apollo Client - 查詢(Batching)合併html

當打開一個客戶端頁面的時候, 客戶端可能會觸發多個請求以完成數據的加載. 有可能會超出瀏覽器併發鏈接的數目, 爲了解決這個問題,咱們經過Query batching一次的請求完成頁面須要的全部數據.git

Query batching 就是在單個請求中包含多個查詢的技術, 它有幾個極其顯著的優勢:github

  • 減小請求數量segmentfault

  • 當多個查詢包含在一個請求中時, 可使用 DataLoader 批量的從後端API或服務器獲取數據.後端

使用

假設一個場景, 多個UI組件都是用了GraphQL查詢從服務器獲取數據. 下面兩個查詢多是由兩個不一樣的UI組件生產的, 會產生兩次客戶端和服務器之間的數據往返.瀏覽器

client.query({ query: query1 })
client.query({ query: query2 })

在Apollo Client中, 查詢批處理默認是關閉的. 要打開查詢批處理, 須要在初始化 Apollo Client的時候打開 shouldBatch 選項:服務器

const client = new ApolloClient({
    // ... 其餘選項
    shouldBatch: true
});

時間間隔

時間間隔標識在一個特定的時間段內(好比100ms), 若是客戶端產生了多個查詢, 那麼Apollo Client會自動把多個查詢合併爲一個.網絡

clipboard.png

查詢合併

查詢合併是由 BatchedNetworkInterface 進行合併的, 下面舉例說明, 如今要執行兩個GraphQL查詢:併發

query firstQuery {
   author {
    firstName
    lastName
  }
}
query secondQuery {
  fortuneCookie
}

咱們想象一下合併的問題, 假設上面的兩個查詢會合併成以下的樣子:app

query ___composed {
  author {
    firstName
    lastName
  }
  fortuneCookie
}

可是, 上述合併後的查詢有幾個問題

  • 依據GraphQL規範, 查詢字段的名稱是不能相同的, 不然會產生命名衝突, 解決這個問題的辦法是使用 alias(別名) 來保證能夠合併任意查詢同時不會讓字段名字發生名稱衝突.

    query ___composed {
      aliasName: author {
        firstName
        lastName
      }
    }
  • 調試的時候服務器應答的字段名稱和客戶端的原始名稱不一致, 給調試帶來麻煩, 解決辦法是在網絡層進行查詢的合併. 當前大多數GraphQL客戶端實現中, 請求時以以下格式發送到服務器的:

    {
      "query": 「< query string goes here >」,
      "variables": {
        <variable values go here>
      }
    }

網絡層的查詢合併

網絡層的查詢合併, 只須要用createBatchingNetworkInterface 替換 createNetworkInterface 便可. 例如:

import ApolloClient, { createBatchingNetworkInterface } from 'apollo-client';
const batchingNetworkInterface = createBatchingNetworkInterface({
  uri: 'localhost:3000',
  batchInterval: 100,
  opts: {
    // Options to pass along to `fetch`
  }
});
const apolloClient = new ApolloClient({
  networkInterface: batchingNetworkInterface,
});
// These two queries happen in quick succession, possibly in totally different
// places within your UI.
apolloClient.query({ query: firstQuery });
apolloClient.query({ query: secondQuery });

結語

上述Batching查詢是正對HTTP這種無狀態協議的, 目的是爲了減小重複創建新的TCP鏈接消耗的時間, 若是採用Websocket這種有狀態協議, 就沒有必要在使用Query Batching, 採用GraphQL Subscriptions.

參考資料

相關文章
相關標籤/搜索