Go:graphql-relay-go(支持 Relay 的辅助库)
GraphQL Relay for Go
graphql-relay-go 是 Go 语言生态中用于构建支持 React Relay 的 GraphQL 服务器的官方辅助库。它基于 graphql-go/graphql 实现,提供了完整的 Relay 服务端规范支持,帮助开发者快速构建符合 Relay 客户端要求的 GraphQL API。
主要特性
该库为 graphql-go 服务器补充了以下 Relay 核心能力:
- Node 接口与全局对象标识:提供
Node接口定义和全局 ID 的编解码工具(MarshalID/UnmarshalID),让客户端能够通过全局 ID 唯一标识和获取任意对象。 - Connection 连接与分页:内置标准的 Connection 参数(
ConnectionArgs)和连接定义工具(ConnectionDefinitions),轻松实现基于游标(cursor)的分页查询。 - Mutation 变更规范:提供
Mutation辅助类型,帮助构建符合 Relay 输入输出约定的变更操作。 - 与
graphql-go无缝集成:完全基于graphql-go的类型系统构建,对现有项目侵入性低。
安装
使用标准的 go get 命令安装:
bash
go get github.com/graphql-go/relay
该库依赖 graphql-go/graphql,安装时会自动拉取。
快速开始
以下示例展示了如何使用 graphql-relay-go 构建一个支持 Relay 的简单服务器。
go
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/graphql-go/graphql"
"github.com/graphql-go/relay"
)
// 定义一个简单的数据模型
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
var users = map[string]User{
"1": {ID: "1", Name: "Alice"},
"2": {ID: "2", Name: "Bob"},
}
// 定义 Node 接口
var nodeDefinitions = relay.NewNodeDefinitions(relay.NodeDefinitionsConfig{
ResolveNode: func(id string, info graphql.ResolveInfo) (interface{}, error) {
return users[id], nil
},
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
if _, ok := p.Value.(User); ok {
return userType
}
return nil
},
})
// 定义 User 对象类型
var userType = graphql.NewObject(graphql.ObjectConfig{
Name: "User",
Interfaces: []*graphql.Interface{
nodeDefinitions.NodeInterface,
},
Fields: graphql.Fields{
"id": relay.GlobalIDField("User", nil),
"name": &graphql.Field{Type: graphql.String},
},
})
// 构建查询类型
var queryType = graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"node": nodeDefinitions.NodeField,
"users": &graphql.Field{
Type: graphql.NewList(userType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
result := make([]User, 0, len(users))
for _, u := range users {
result = append(result, u)
}
return result, nil
},
},
},
})
// 创建 Schema
var schema, _ = graphql.NewSchema(graphql.SchemaConfig{
Query: queryType,
})
func main() {
http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
var params struct {
Query string `json:"query"`
}
if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
result := graphql.Do(graphql.Params{
Schema: schema,
RequestString: params.Query,
})
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
})
fmt.Println("GraphQL server running on :8080/graphql")
log.Fatal(http.ListenAndServe(":8080", nil))
}
在上述示例中:
relay.NewNodeDefinitions注册了 Node 接口,用于将全局 ID 解析为对应的数据对象。relay.GlobalIDField自动将内部 ID 编码为 Relay 规定的全局 ID 格式。nodeDefinitions.NodeField暴露了node查询入口,客户端可通过该入口获取任意对象。
核心功能说明
全局 ID 编解码
Relay 要求所有对象通过全局 ID 引用。graphql-relay-go 提供了以下工具:
relay.MarshalID(typeName, id):将类型名与内部 ID 编码为全局 ID。relay.UnmarshalID(globalID):将全局 ID 解码回类型名与内部 ID。relay.GlobalIDField(typeName, resolve):快速定义对象类型中的id字段。
连接与分页
对于列表类字段,Relay 规范推荐使用 Connection 类型实现基于游标的分页:
go
var userConnection = relay.ConnectionDefinitions(relay.ConnectionConfig{
Name: "User",
NodeType: userType,
})
var queryFields = graphql.Fields{
"users": &graphql.Field{
Type: userConnection.ConnectionType,
Args: relay.ConnectionArgs,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
// 从 p.Args 中读取 First, Last, Before, After 参数
// 实现分页逻辑并返回 []User
return nil, nil
},
},
}
relay.ConnectionArgs 提供了标准的分页参数(first、last、before、after),ConnectionDefinitions 则自动生成 XxxConnection、XxxEdge 等类型。
Mutation 变更
Relay 的 Mutation 规范要求输入和输出都遵循特定结构。该库通过 relay.Mutation 和辅助函数简化了这一过程:
go
var updateUserMutation = relay.Mutation(relay.MutationConfig{
Name: "UpdateUser",
InputFields: graphql.InputObjectConfigFieldMap{
"id": &graphql.InputObjectFieldConfig{Type: graphql.NewNonNull(graphql.String)},
"name": &graphql.InputObjectFieldConfig{Type: graphql.String},
},
OutputFields: graphql.Fields{
"user": &graphql.Field{Type: userType},
},
MutateAndGetPayload: func(p relay.MutationPayload) (interface{}, error) {
// p.Input 包含输入参数
// p.Context 包含请求上下文
return nil, nil
},
})
相关资源
- GitHub 仓库:github.com/graphql-go/relay
- 底层 GraphQL 实现:graphql-go/graphql
- Relay 规范:Relay GraphQL Server Specification
总结
graphql-relay-go 是连接 Go 后端与 Relay 前端的重要桥梁。它忠实实现了 Relay 服务端规范,将全局 ID、游标分页、规范化变更等复杂协议细节封装为简洁的 API,使 Go 开发者能够专注于业务逻辑,快速构建出可被 Relay 客户端直接消费的 GraphQL 服务。对于使用 Relay 作为前端数据层、同时倾向 Go 作为后端语言的团队,这是一个值得优先考虑的官方方案。
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
