2020 年 12 月 8 日作者Rob Richard、Liliana Matos
Rob Richard 和 Liliana Matos 是 1stDibs.com 的前端工程師。他們一直與 GraphQL 工作小組合作,擔任
@defer
和@stream
指令的倡導者。
自從 Lee Byron 在 2016 年 GraphQL 歐洲大會 上首次談論 @defer
和 @stream
指令以來,它們就一直備受期待。在 2020 年的大部分時間裡,我們一直與 GraphQL 工作小組合作,以標準化此功能。它現在是第 2 階段提案,但為了進一步推進,我們希望 GraphQL 社群嘗試使用這些指令並提供回饋。我們已發布 GraphQL.js
和 express-graphql
的實驗版本。它們在 npm 上以 graphql@experimental-stream-defer
和 express-graphql@experimental-stream-defer
發布。我們鼓勵所有對此功能感興趣的人試用這些版本,並在 為回饋建立的問題 中讓我們知道進度。繼續閱讀以進一步了解此提案提供的內容。
GraphQL 請求/回應模型的缺點之一是,在整個請求處理完成之前,不會將 GraphQL 回應傳回給客戶端。但是,並非所有請求的資料都同等重要,在某些使用案例中,應用程式有可能針對請求資料的子集採取行動。如果 GraphQL 伺服器可以在準備好時立即傳送最重要的資料,應用程式可以縮短其互動時間。新的 @defer
和 @stream
指令允許 GraphQL 伺服器執行此操作,方法是從單一 GraphQL 回應傳回多個酬載。
@defer
指令可以套用至片段散佈和內嵌片段。這是開發人員宣告查詢部分為非立即回傳必要的宣告方式。
以下是 @defer
指令的範例
query { person(id: "cGVvcGxlOjE=") { name ...HomeworldFragment @defer(label: "homeworldDefer") }}
fragment HomeworldFragment on Person { homeworld { name }}
酬載 1
{ "data": { "person": { "name": "Luke Skywalker" } }, "hasNext": true}
酬載 2
{ "label": "homeworldDefer", "path": ["person"], "data": { "homeworld": { "name": "Tatooine" } }, "hasNext": false}
當 GraphQL 執行引擎遇到 @defer
指令時,它會分岔執行並開始非同步解析那些欄位。在遞延酬載仍準備中的同時,客戶端可以接收並針對初始酬載採取行動。當遞延資料龐大、載入成本高昂或不在互動性的關鍵路徑上時,這項功能最為有用。
與 @defer
類似,@stream
指令也允許客戶端在整個結果準備好之前接收資料。@stream
可以用於清單欄位。以下是 @stream
指令的範例
query { person(id: "cGVvcGxlOjE=") { name films @stream(initialCount: 2, label: "filmsStream") { title }}
酬載 1
{ "data": { "person": { "name": "Luke Skywalker", "films": [ { "title": "A New Hope" }, { "title": "The Empire Strikes Back" } ] } }, "hasNext": true}
酬載 2
{ "label": "filmsStream", "path": ["person", "films", 2], "data": { "title": "Return of the Jedi" }, "hasNext": true}
酬載 3
{ "label": "filmsStream", "path": ["person", "films", 3], "data": { "title": "Revenge of the Sith" }, "hasNext": false}
當 GraphQL 執行引擎遇到 @stream
指令時,它將解析由 initialCount
參數指定的許多清單項目。其餘項目將會非同步解析。這對於只能在摺疊上方呈現少數元素的介面特別有用。伺服器仍在解析其餘資料時,客戶端可以盡快呈現這些元素。
儘管 GraphQL 規範未指定傳輸協定,我們預期具有 @defer
/@stream
的查詢最常見的傳輸將是具有分塊傳輸編碼的 HTTP。這允許 GraphQL 伺服器保持標準 HTTP 連線開啟,同時在準備就緒時將每個酬載串流傳輸到客戶端。它具有低負載,數十年來一直受到瀏覽器的支援,並且可以輕鬆與大多數基礎架構搭配使用。
您可以在以下位置瞭解更多關於這些指令的資訊
– Rob Richard、Liliana Matos,前端工程,1stDibs.com