使用 Go 构建 GraphQL API:面向初学者的分步教程

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

GraphQL 与 Go 简介

GraphQL 是一种 API 查询语言,它允许客户端精确获取所需的数据,不多不少。与每个端点返回固定数据结构的 REST 不同,GraphQL 提供了灵活性和控制力。结合 Go (Golang) —— 一种快速、类型安全且简单的语言 —— 您将获得一个构建现代 Web 服务的强大工具。

在本教程中,我们将从零开始,使用 Go 创建一个简单的 GraphQL API。您将学习如何安装依赖项、描述模式、实现解析器以及启动服务器。本文面向初学者,因此所有步骤都有详细解释。



1. 项目准备与依赖安装

在编写代码之前,请确保您已安装 Go 1.18 或更高版本。为项目创建一个新目录并初始化模块:

mkdir graphql-go-tutorialcd graphql-go-tutorialgo mod init graphql-go-tutorial


选择库:gqlgen

有多个库可用于在 Go 中处理 GraphQL。我们将使用 gqlgen —— 一个流行的代码生成器,它根据模式创建类型和解析器。安装它:

go get github.com/99designs/gqlgen@latest


初始化 gqlgen

执行以下命令以创建默认文件:

go run github.com/99designs/gqlgen init

此命令将创建几个文件:

  • graph/schema.graphqls —— GraphQL 模式文件;
  • graph/resolver.go —— 解析器模板;
  • server.go —— 服务器入口点;
  • gqlgen.yml —— 生成配置。


2. 描述 GraphQL 模式

打开文件 graph/schema.graphqls。默认情况下,其中已有一个 Todo 类型的示例。我们将通过添加 User 类型和一些查询来扩展它。

将文件内容替换为以下内容:

type User {    id: ID!    name: String!    email: String!}

type Todo { id: ID! text: String! done: Boolean! user: User!}

type Query { todos: [Todo!]! users: [User!]! user(id: ID!): User}

type Mutation { createTodo(text: String!, userId: ID!): Todo! markDone(id: ID!): Todo!}

这里我们定义了:

  • User —— 包含 id、name、email 字段的用户。
  • Todo —— 包含 id、text、done 字段以及用户引用的任务。
  • Query —— 用于读取数据的入口点。
  • Mutation —— 用于修改数据的操作。


3. 代码生成与解析器实现

描述模式后,需要生成 Go 代码。执行:

go run github.com/99designs/gqlgen generate

这将创建文件 models_gen.go 并更新 resolver.go。现在打开 graph/resolver.go。



添加数据存储

为简单起见,我们将数据存储在内存中。在 resolver.go 中添加结构体:

type Resolver struct {    Users []*model.User    Todos []*model.Todo}

不要忘记导入 model 包。



实现查询 (Query)

找到为 Query 生成的方法。实现它们:

func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) {    return r.Resolver.Todos, nil}

func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) { return r.Resolver.Users, nil}

func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) { for _, u := range r.Resolver.Users { if u.ID == id { return u, nil } } return nil, fmt.Errorf("user not found")}

博客

书籍推荐