加入我们,从10月8日至10日,在新 York City 学习有关 GraphQL 联盟和 API 平台工程的最新技巧、趋势和新闻。参加2024年在纽约市的 GraphQL 大会
文档
免费开始

查询批处理

使用 GraphOS Router 接收查询批次


此功能仅在 GraphOS 企业计划中可用.
您可以通过注册免费账户来测试它。 企业试用版.

了解关于批处理和如何配置以接收查询批处理。

关于查询批处理

现代应用程序通常需要多个请求来渲染单个页面。这通常是组件化架构的结果,其中单独的微前端(MFE)分别发出请求以获取与其相关的数据。这不仅会导致性能开销——不同的组件可能请求相同的数据——还可能导致一致性问题。为了解决这个问题,基于MFE的用户界面将多个彼此紧密相连的客户组合成一个单独的HTTP请求。这在中得到支持。

路由器的批处理支持通过两组功能提供:

  • 客户端批处理
  • 批处理

在客户端批处理中,路由器从客户端接收批处理请求,并单独处理批处理中的每个请求。因此,路由器以批量形式向呈现请求,因此子图必须单独处理批处理请求。

在子图批处理中,路由器分析输入客户端批处理请求并向子图发出批处理请求。子图批处理是客户端批处理的扩展,需要参与的子图支持批处理请求。以下是说明如何在实践中工作的示例。

GraphOS 路由器支持客户端和子图查询批处理。

如果您使用的是Apollo 客户端,则可以利用内置的批处理支持来减少发送到路由器的单独操作的数量。

配置后,Apollo 客户端将自动将多个操作组合成一个单独的HTTP请求。批次内的操作数量由客户端配置,包括批次中的最大数量和等待操作累积发送批次的最大持续时间。

GraphOS 路由器必须配置为接收查询批次,否则它将拒绝它们。在处理批处理时,路由器将单独反序列化和处理批处理中的每个。仅在批次中的所有操作都完成后,才对客户端做出响应。每个操作与其他批处理中的操作并发执行。

配置客户端查询批处理

GraphOS 路由器和客户端都需要配置以支持查询批处理。

配置路由器

客户端查询批处理

默认情况下,GraphOS 路由器启用接收客户端查询批次。

要启用查询批量处理,请设置以下在您的router.yaml配置文件中:

router.yaml
batching:
enabled: true
mode: batch_http_link
属性描述有效值默认值
enabled启用接收客户端查询批次的标志布尔类型false
mode支持客户端批量模式batch_http_link:客户端使用 Apollo Link 及其 BatchHttpLink 连接。无默认值

子图查询批量处理

如果启用客户端查询批量处理,并且路由器的子图支持查询批量处理,则可以通过设置以下字段在您的router.yaml配置文件中启用子图查询批量处理:

router.all_enabled.yaml
batching:
enabled: true
mode: batch_http_link
subgraph:
# Enable batching on all subgraphs
all:
enabled: true
router.yaml
batching:
enabled: true
mode: batch_http_link
subgraph:
# Disable batching on all subgraphs
all:
enabled: false
# Configure(over-ride) batching support per subgraph
subgraphs:
subgraph_1:
enabled: true
subgraph_2:
enabled: true

注意

  • 路由器可以被配置为支持所有子图的批量处理或为每个子图单独启用。

  • 路由器从客户端请求中保留批量到子图请求的能力有限。特别是,某些形式的查询在处理之前需要存在数据。因此,路由器只能从不需要这种约束的查询生成批次。这可能导致路由器发布多个批次或请求。

  • 如果启用了查询去重实体缓存,它们将不会应用于批量查询。批量处理将优于查询去重和。对于非批量查询,仍将执行查询去重和实体缓存。

示例:简单的子图批量处理

此示例显示路由器如何在查询批次中不包含必需的获取约束的最多效场景中对子图请求进行批量处理。

假设联邦的包含三个子图accountsproductsreviews

输入客户端 查询到联盟

simple-batch.json
[
{"query":"query MeQuery1 {\n me {\n id\n }\n}"}
{"query":"query MeQuery2 {\n me {\n name\n }\n}"},
{"query":"query MeQuery3 {\n me {\n id\n }\n}"}
{"query":"query MeQuery4 {\n me {\n name\n }\n}"},
{"query":"query MeQuery5 {\n me {\n id\n }\n}"}
{"query":"query MeQuery6 {\n me {\n name\n }\n}"},
{"query":"query MeQuery7 {\n me {\n id\n }\n}"}
{"query":"query MeQuery8 {\n me {\n name\n }\n}"},
{"query":"query MeQuery9 {\n me {\n id\n }\n}"}
{"query":"query MeQuery10 {\n me {\n name\n }\n}"},
{"query":"query MeQuery11 {\n me {\n id\n }\n}"}
{"query":"query MeQuery12 {\n me {\n name\n }\n}"},
{"query":"query MeQuery13 {\n me {\n id\n }\n}"}
{"query":"query MeQuery14 {\n me {\n name\n }\n}"},
{"query":"query MeQuery15 {\n me {\n id\n }\n}"}
]

从输入 查询中,路由器 生成了一个子图 查询集:

"query MeQuery1__accounts__0{me{id}}",
"query MeQuery2__accounts__0{me{name}}",
"query MeQuery3__accounts__0{me{id}}",
"query MeQuery4__accounts__0{me{name}}",
"query MeQuery5__accounts__0{me{id}}",
"query MeQuery6__accounts__0{me{name}}",
"query MeQuery7__accounts__0{me{id}}",
"query MeQuery8__accounts__0{me{name}}",
"query MeQuery9__accounts__0{me{id}}",
"query MeQuery10__accounts__0{me{name}}",
"query MeQuery11__accounts__0{me{id}}",
"query MeQuery12__accounts__0{me{name}}",
"query MeQuery13__accounts__0{me{id}}",
"query MeQuery14__accounts__0{me{name}}",
"query MeQuery15__accounts__0{me{id}}",

所有的查询可以合并成一个批次。因此,而不是15个(非批量)子图 获取操作,路由器 只需要进行一次获取。

子图获取次数(无)获取次数(有)
账户151
示例:复杂的子图批量处理

此示例展示了路由器如何批量处理某图中的子图 请求,其中客户端批次包含对一个 查询的

假设联盟 图包含三个 子图accountsproductsreviews

输入客户端 查询到联盟

federated-batch.json
[
{"query":"query MeQuery1 {\n me {\n id\n }\n}"},
{"query":"query MeQuery2 {\n me {\n reviews {\n body\n }\n }\n}"},
{"query":"query MeQuery3 {\n topProducts {\n upc\n reviews {\n author {\n name\n }\n }\n }\n me {\n name\n }\n}"},
{"query":"query MeQuery4 {\n me {\n name\n }\n}"},
{"query":"query MeQuery5 {\n me {\n id\n }\n}"}
]

从输入 查询中,路由器 生成了一个子图 查询集:

"query MeQuery1__accounts__0{me{id}}",
"query MeQuery2__accounts__0{me{__typename id}}",
"query MeQuery3__products__0{topProducts{__typename upc}}",
"query MeQuery3__accounts__3{me{name}}",
"query MeQuery4__accounts__0{me{name}}",
"query MeQuery5__accounts__0{me{id}}",
"query MeQuery2__reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{body}}}}",
"query MeQuery3__reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{author{__typename id}}}}}",
"query MeQuery3__accounts__2($representations:[_Any!]!){_entities(representations:$representations){...on User{name}}}",

前六个查询可以合并成两个批次——一个用于 accounts,一个用于products。它们必须先获取,才能单独执行最后的三个查询。

总的来看,没有子图批处理后,路由器在三个子图上总共进行9次获取,但有了子图批处理后,总数减少到5次。

子图获取次数(无)获取次数(有)
账户62
products11
reviews22

配置客户端

要在 Apollo 客户端中启用批量处理,请配置 BatchHttpLink。有关实现 BatchHttpLink的详细信息,请参阅 批量操作

配置兼容性

如果路由器从一个客户端接收查询批量,且批量处理 未启用,则路由器向客户端发送一个 BATCHING_NOT_ENABLED 错误。

查询批量的指标

GraphOS Router 中查询批量的指标:

名称属性描述
apollo.router.operations.batching

模式 [subgraph]

接收(来自客户端)或派发(到子图)批量的计数器。

apollo.router.operations.batching.size

模式 [subgraph]

接收批量大小的直方图。

如果存在 subgraph 属性,则是可选的。如果不存在该属性,则指标标识来自客户端的批量。如果存在该属性,则指标标识发送到特定 subgraph 的批量。

查询批量格式

请求格式

查询批量是一系列的 operations 数组。

[
query MyFirstQuery {
me {
id
}
},
query MySecondQuery {
me {
name
}
}
]

响应格式

响应以 JSON 数组形式提供,其中响应顺序与查询批量中操作的顺序相匹配。

[
{"data":{"me":{"id":"1"}}},
{"data":{"me":{"name":"Ada Lovelace"}}}
]

查询批量的错误处理

批量错误

如果无法处理查询批量,则整个批量会失败。

例如,此批量请求是无效的,因为它有两个逗号分隔构成查询。

[
query MyFirstQuery {
me {
id
}
},,
query MySecondQuery {
me {
name
}
}
]

因此,路由器返回一个无效批量错误:

{"errors":
[
{"message":"Invalid GraphQL request","extensions":{"details":"failed to deserialize the request body into JSON: expected value at line 1 column 54","code":"INVALID_GRAPHQL_REQUEST"}}
]
}

单个查询错误

如果在批量中单个查询无法处理,这将导致单个错误。

例如,查询 MyFirstQuery 访问一个不存在的 ,而其余的批处理查询是有效的。

[
query MyFirstQuery {
me {
thisfielddoesnotexist
}
},
query MySecondQuery {
me {
name
}
}
]

因此,对单个无效查询返回一个错误,而其他(有效)查询返回一个响应。

[
{"errors":
[
{"message":"cannot query field 'thisfielddoesnotexist' on type 'User'",
"extensions":{"type":"User","field":"thisfielddoesnotexist","code":"INVALID_FIELD"}
}
]
},
{"data":{"me":{"name":"Ada Lovelace"}}}
]

已知限制

不支持的查询模式

启用批量处理时,任何导致响应流的结果的批量操作都不受支持,包括:

Previous
请求格式
Next
订阅设置
评级文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,即Apollo GraphQL。

隐私政策

公司