如何用 HttpGraphQlClient 发送仅含 SHA-256 的持久化查询?
数据小许
结论
HttpGraphQlClient 的 GraphQlClient 请求接口要求提供 GraphQL 文档。extensions(...) 用于添加扩展字段,不能省略必需的文档参数。因此,使用 document(null) 无法可靠地构造“只发送哈希、不发送 query”的请求。若服务端支持 Apollo 风格的 Automatic Persisted Queries(APQ),可以通过 WebClient 直接发送 HTTP POST,并在请求体中只包含 extensions。
documentName(...) 不能用来指定持久化查询 ID。它会通过配置的 DocumentSource 查找本地文档,再发送解析出的文档内容。Spring GraphQL 客户端文档说明了文档文本和文档名的用途;GraphQlClient API将 document(String) 定义为提供要执行的文档。
使用 WebClient 发送 APQ 请求
如果服务端支持 Apollo 风格的 APQ,且该哈希已在服务端注册,请求体可以这样写:
{
"extensions": {
"persistedQuery": {
"version": 1,
"sha256Hash": "查询文档对应的SHA-256哈希"
}
}
}
使用 WebClient 发送请求:
String hash = "查询文档对应的SHA-256哈希";
Mono<String> response = webClient.post()
.uri("/graphql")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(Map.of(
"extensions", Map.of(
"persistedQuery", Map.of(
"version", 1,
"sha256Hash", hash))))
.retrieve()
.bodyToMono(String.class);
如果查询需要变量,请按服务端约定在 JSON 请求体中加入 variables 字段。上例中的 /graphql 需要替换为实际的 GraphQL 端点。如果 webClient 已配置完整 URL,也可以相应调整 URI。
注意事项
extensions.persistedQuery的格式遵循 APQ 约定。将查询保存在服务端,并不代表服务端一定支持该协议。请确认服务端接受此扩展及其字段格式。Persisted Operations 提案介绍了持久化操作相关的请求机制。- 哈希必须与服务端存储文档时采用的内容和计算方式一致。如果服务器使用不同的规范化或编码规则,同一查询也可能得到不同的哈希。
- 不建议用
document("")替代省略query。这样传入的是空字符串文档,并非从请求体中省略query;服务端是否接受取决于具体实现。 - 如果需要保留
HttpGraphQlClient的响应处理或拦截链,可以考虑实现自定义传输或客户端包装层,在 HTTP 层生成符合服务端要求的请求体。具体实现取决于所用的 Spring GraphQL 版本和现有客户端配置。
备注:内容仅供参考。
