摘要
Sui 在其 gRPC 和 JSON-RPC 接口之外还提供了一个 GraphQL 端点,内省功能让你可以在运行时发现 schema,而无需猜测字段名称。本教程展示如何发送内省查询、读取响应,并利用 schema 构建针对 Sui 数据的有效查询。它还涵盖了何时内省是合适的工具,以及何时专用节点或托管 RPC 端点更适合生产工作负载。
Sui 在其 gRPC 和 JSON-RPC API 之外还提供了一个 GraphQL 接口。GraphQL 提供了类型化的 schema,因此你无需记住方法名称,而是可以询问端点它支持什么。这正是内省查询所做的:它返回 schema 本身,包括类型、字段、参数和描述。
本教程将引导你向 Sui GraphQL 端点发送内省查询、读取响应,并将该 schema 转化为可用的查询。它还涵盖了开发者接下来会遇到的实践问题:你应该将内省和应用流量指向共享端点,还是迁移到专用基础设施?
何时内省是正确选择(何时不是)
内省是开发和工具功能,不是生产数据路径。当你探索 schema、生成类型化客户端,或在网络升级后验证某个字段是否仍然存在时,请使用它。
| 情况 | 使用内省? | 更好的替代方案 |
|---|---|---|
| 首次构建类型化客户端 | 是 | 内省 + 代码生成 |
| 查询突然返回字段错误 | 是,确认字段名称 | 检查 schema 差异 |
| 高流量生产读取 | 否 | 在专用节点上使用固定查询 |
| 调试单笔交易 | 否 | 按摘要进行针对性查询 |
| CI schema 兼容性检查 | 是 | 自动化内省差异 |
如果你仍在决定使用 Sui 的哪个接口,Sui API 概述 是在你决定使用 GraphQL 之前的一个良好起点。
Sui GraphQL 端点基础
Sui GraphQL 端点接受 HTTP POST 请求,请求体为 JSON,包含一个 query 字符串和可选的 variables。端点是单个 URL;你通过查询本身而不是不同的路径来选择数据形状。
在发送内省查询之前,请确认三件事:
- 你目标端点的 URL(主网或测试网)。
- 端点接受
application/jsonPOST 请求体。 - 端点在生生产环境中是否限制内省。
一些托管提供商在共享端点上禁用内省以减少负载,而专用节点通常保持启用。如果内省返回关于被禁用的错误,那是配置选择,而不是你的查询中的错误。
发送你的第一个内省查询
标准内省查询很冗长,因为它遍历整个类型系统。先从较小的查询开始,列出根查询字段,然后在确认端点响应后再扩展。
curl -s https://your-sui-graphql-endpoint.example/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ __schema { queryType { name } types { name kind } } }"
}'
将占位符 URL 替换为你的提供商提供的 GraphQL 端点。响应包含一个 data.__schema 对象。queryType.name 告诉你根查询类型的名称,types 列出 schema 中的每个类型及其 kind(OBJECT、SCALAR、ENUM、INPUT_OBJECT 等)。
如果返回了 data 对象,则端点正常工作。如果返回了 errors 数组,请仔细阅读消息;它通常会告诉你问题是认证、功能禁用还是查询格式错误。
读取 schema 响应
完整的内省结果很大。与其将其转储到终端,不如将其管道传输到文件并在本地查询。
curl -s https://your-sui-graphql-endpoint.example/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"{ __schema { types { name kind fields { name } } } }"}' \
> sui-schema.json
现在你可以使用 jq 检查它:
jq '.data.__schema.types[] | select(.name == "Query") | .fields[].name' sui-schema.json
该命令列出根查询类型上可用的顶级字段。从那里你可以深入任何类型以查看其字段和参数。这是回答诸如“交易摘要的确切字段名是什么”之类问题的最快方式,而无需阅读外部文档。
将 schema 转化为可用的查询
一旦你知道字段名称,就构建一个小查询并测试它。一个典型模式是通过标识符获取单个对象,并只选择你需要的字段。
const query = `
query GetObject($id: SuiAddress!) {
object(address: $id) {
address
version
digest
}
}
`;
const res = await fetch("https://your-sui-graphql-endpoint.example/graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query, variables: { id: "0x..." } })
});
const json = await res.json();
console.log(json.data);
确切的字段名称和参数类型来自你的内省结果,因此将上面的代码片段视为一种形状,而不是复制粘贴的保证。如果你的端点上字段名称不同,schema 是事实来源。
CI 中的内省:捕获 schema 漂移
Sui 的 schema 会演变。字段会被添加、弃用或重命名。如果你的应用依赖于一个消失的字段,除非你提前检查,否则你会在生产环境中发现。
一个实用的模式是存储内省结果的快照,并在每次部署时进行比较:
# 保存一次基线
curl -s $SUI_GRAPHQL_ENDPOINT -H 'Content-Type: application/json' \
-d '{"query":"{ __schema { types { name kind fields { name } } } }"}' \
> schema-baseline.json
# 在 CI 中,获取当前 schema 并比较差异
curl -s $SUI_GRAPHQL_ENDPOINT -H 'Content-Type: application/json' \
-d '{"query":"{ __schema { types { name kind fields { name } } } }"}' \
> schema-current.json
diff <(jq -S . schema-baseline.json) <(jq -S . schema-current.json)
非空差异不一定是失败,但它是一个信号,表明需要审查你的查询是否仍然匹配 schema。这在网络升级之前特别有用。
常见内省错误及其含义
| 症状 | 可能原因 | 下一步 |
|---|---|---|
Introspection is disabled | 提供商在共享端点上阻止了它 | 使用专用节点或允许它的提供商 |
Cannot query field | 字段名称更改或拼写错误 | 重新运行内省并检查类型 |
401 或 403 | 缺少或无效的 API 密钥 | 检查你的提供商要求的认证头 |
空 data 带 errors | 查询语法问题 | 验证查询字符串 |
| 完整内省超时 | 响应对于端点太大 | 请求更窄的类型子集 |
如果你在完整内省查询上反复遇到超时,只请求你关心的类型。内省支持通过遍历特定类型而不是整个 schema 来进行过滤。
为内省和应用流量选择端点
内省偶尔运行成本低,但频繁运行则成本高。你用于 schema 探索的端点不必与应用用于生产读取的端点相同。
一种常见的划分如下:
- 开发和 CI: 允许内省的托管端点,用于代码生成和 schema 差异。
- 生产读取: 具有固定查询、可预测容量且无内省开销的专用节点。
OnFinality 为 Sui 提供 RPC API 访问 和 专用节点基础设施。如果你想了解如何权衡共享端点与专用端点,关于 选择 RPC 提供商 的指南涵盖了这些权衡,而 RPC 定价 展示了计划的结构。你还可以查看 支持的 RPC 网络 以了解 Sui 在更广泛阵容中的位置。
关键要点
- Sui GraphQL 内省查询返回 schema,让你在运行时发现类型和字段。
- 从窄内省查询开始,然后在端点响应后扩展。
- 将大响应管道传输到文件,并使用
jq检查它们,而不是读取原始 JSON。 - 一些共享端点禁用内省;专用节点通常允许它。
- 存储 schema 快照并在 CI 中比较差异,以在生产环境被破坏之前捕获 schema 漂移。
- 将你的 schema 探索端点与生产读取路径分开。
常见问题
Sui GraphQL 支持标准内省查询吗?
是的,Sui 的 GraphQL 接口遵循 GraphQL 规范,因此 __schema 和 __type 内省字段在端点允许内省的地方可以工作。
为什么我的端点上内省返回错误? 最常见的原因是提供商在共享端点上禁用内省以减少负载。检查你的提供商的文档或迁移到专用节点。
我可以使用内省生成类型化客户端吗? 是的。保存内省结果并将其提供给 GraphQL 代码生成器,以生成你语言的类型化查询。
在生产环境中运行内省安全吗? 偶尔运行是安全的,但它不是数据路径。将其保留在开发和 CI 中,并为生产流量使用固定查询。
Sui GraphQL schema 多久更改一次? Schema 随网络升级而演变。在 CI 中比较存储的快照是了解变化的最简单方法。
我需要专用节点才能使用 GraphQL 吗? 不,但专用节点提供一致的访问并避免共享端点限制,例如禁用的内省。有关端点选项,请参阅 Sui RPC。