Relay 节点接口
在本部分我们继续 GraphQL 示例 解释如何实现 Relay 节点接口。 如果你不熟悉节点接口,参阅 relay.dev 摘录的如下段落:
为使 GraphQL 客户端能够优雅地处理缓存和数据重新获取,GraphQL 服务器需要以标准化方式暴露对象标识符。 在查询中,模式应为通过 ID 请求对象提供标准机制。 在响应中,模式提供返回这些 ID 的标准方式。
我们用标识符来代表对象,称之为 “节点(nodes)”。以下查询是包括这两者的示例:
{
node(id: "4") {
id
... on User {
name
}
}
}
克隆代码(可选)
本教程代码可以在 github.com/a8m/ent-graphql-example 找到, 并在每一步都打了标签(使用 Git)。 如果你想要跳过基础安装并使用 GraphQL 最初的版本,你可以像如下克隆代码仓库:
git clone git@github.com:a8m/ent-graphql-example.git
cd ent-graphql-example
go run ./cmd/todo/
实现
Ent 通过 GraphQL 集成实现节点接口。通过下面几个步骤你可以在你的应用程序中支持它。
我们需要告知 gqlgen:Ent 通过像如下一样编辑 gqlgen.yaml 文件提供 Node 接口:
# This section declares type mapping between the GraphQL and Go type systems.
models:
# Defines the ID field as Go 'int'.
ID:
model:
- github.com/99designs/gqlgen/graphql.IntID
Node:
model:
- todo/ent.Noder
我们再次运行代码生成应用这些修改:
go generate .
像之前一样,我们需要在 ent.resolvers.go 中实现 GraphQL 解析器。
只需要修改一行代码,我们就能通过替换生成的 gqlgen 代码实现这些,如下:
func (r *queryResolver) Node(ctx context.Context, id int) (ent.Noder, error) {
- panic(fmt.Errorf("not implemented: Node - node"))
+ return r.client.Noder(ctx, id)
}
func (r *queryResolver) Nodes(ctx context.Context, ids []int) ([]ent.Noder, error) {
- panic(fmt.Errorf("not implemented: Nodes - nodes"))
+ return r.client.Noders(ctx, ids)
}
查询节点
现在我们准备测试新的 GraphQL 解析器。 让我们通过运行多次查询(变量的修改是可选的)开始创建几条待办事项:
mutation CreateTodo($input: CreateTodoInput!) {
createTodo(input: $input) {
id
text
createdAt
priority
parent {
id
}
}
}
# Query Variables: { "input": { "text":"Create GraphQL Example", "status": "IN_PROGRESS", "priority": 1 } }
# Output: { "data": { "createTodo": { "id": "2", "text": "Create GraphQL Example", "createdAt": "2021-03-10T15:02:18+02:00", "priority": 1, "parent": null } } }
在其中之一待办事项条目上运行 Node API 会返回:
query {
node(id: 1) {
id
... on Todo {
text
}
}
}
# Output: { "data": { "node": { "id": "1", "text": "Create GraphQL Example" } } }
在其中之一待办事项条目上运行 Nodes API 会返回:
query {
nodes(ids: [1, 2]) {
id
... on Todo {
text
}
}
}
# Output: { "data": { "nodes": [ { "id": "1", "text": "Create GraphQL Example" }, { "id": "2", "text": "Create Tracing Example" } ] } }
做得很好!正如你所见,通过修改几行代码我们的应用程序现在实现了 Relay 节点接口。 在下一部分,我们将会展示如果使用 Ent 实现 Relay 游标连接,这对于应用程序支持查询结果的切片和分页很有用。