Go (Golang) 的 GraphQL 库 — 创建 API 的强大工具
GraphQL 是一种 API 查询语言,允许客户端仅请求他们真正需要的数据。在 Go (Golang) 生态系统中,最流行的 GraphQL 库之一是 gqlgen (GraphQL Go Generate)。该库允许您以最少的样板代码创建类型安全的 GraphQL 服务器。在本文中,我们将详细介绍 gqlgen、其安装、配置和使用示例。
什么是 gqlgen?
gqlgen 是一个 Go 代码生成器,它根据您的 GraphQL 模式自动创建解析器和类型。主要优点:
- 类型安全 — 所有类型在编译时进行检查
- 最少的样板代码 — 库为您生成大部分代码
- 灵活性 — 支持订阅、变更和复杂查询
- 性能 — Go 特有的高速运行
安装 gqlgen
首先,安装库和命令行工具:
go get github.com/99designs/gqlgengo run github.com/99designs/gqlgen initinit 命令将创建包含 schema.graphqls、gqlgen.yml 文件和生成代码的基本项目结构。
项目结构
初始化后,您将获得以下结构:
my-graphql-app/├── gqlgen.yml # 生成器配置├── graph/│ ├── schema.graphqls # GraphQL 模式│ ├── resolver.go # 解析器(您的代码)│ └── models_gen.go # 生成的模型(请勿编辑)├── server.go # 入口点└── go.mod编写 GraphQL 模式
一个简单博客的 schema.graphqls 文件示例:
type Query { posts: [Post!]! post(id: ID!): Post}
type Mutation { createPost(input: PostInput!): Post! deletePost(id: ID!): Boolean!}
type Post { id: ID! title: String! content: String! author: String! createdAt: Time!}
input PostInput { title: String! content: String! author: String!}
scalar Time代码生成
描述模式后,执行:
go run github.com/99designs/gqlgen generate这将创建包含类型和解析器接口的 models_gen.go 和 generated.go 文件。
实现解析器
现在需要在 resolver.go 中实现逻辑:
package graph
import ( "context" "time")
// 数据模型type Post struct { ID string `json:"id"` Title string `json:"title"` Content string `json:"content"` Author string `json:"author"` CreatedAt time.Time `json:"createdAt"`}
// 内存存储var posts = []*Post{ { ID: "1", Title: "GraphQL 入门", Content: "GraphQL 是一种查询语言...", Author: "Ivan Petrov", CreatedAt: time.Now(), },}
// Query.posts 的解析器func (r *queryResolver) Posts(ctx context.Context) ([]*Post, error) { return posts, nil}
// Query.post 的解析器func (r *queryResolver) Post(ctx context.Context, id string) (*Post, error) { for _, post := range posts { if post.ID == id { return post, nil } } return nil, nil}
// Mutation.createPost 的解析器func (r *mutationResolver) CreatePost(ctx context.Context, input PostInput) (*Post, error) { newPost := &Post{ ID: fmt.Sprintf("%d", len(posts)+1), Title: input.Title, Content: input.Content, Author: input.Author, CreatedAt: time.Now(), } posts = append(posts, newPost)