PAYATHON 2026

如何用 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 版本和现有客户端配置。

备注:内容仅供参考。