Go语言API:REST、GraphQL和gRPC——2025年如何选择

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

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

开始课程

为什么Go是构建API的理想语言?

\n\n

当谈到构建高负载API时,Go(Golang)稳居前列。其编译型特性、通过goroutine实现的并发支持以及简洁的语法,让开发者能够编写快速且可靠的微服务。但您应该为下一个项目选择哪种协议:经典的REST、灵活的GraphQL,还是超高速的gRPC?

\n\n

本文不仅会列出它们的区别——我们将为每种方法编写真实的Go代码,分析性能基准测试,并提供清晰的选择标准。让我们开始吧!

\n\n

Go语言中的REST API:久经考验的经典

\n\n

REST(表述性状态转移)仍然是公共API的事实标准。Go提供了出色的标准库net/http,以及像gin和echo这样的流行框架。

\n\n

纯Go编写的REST服务器示例

\n\n

让我们从一个简单的任务管理CRUD服务开始。以下是一个无需第三方依赖的最小化Go REST API:

\n\n
package main\n\nimport (\n    "encoding/json"\n    "log"\n    "net/http"\n    "sync"\n)\n\ntype Task struct {\n    ID   int    `json:"id"`\n    Name string `json:"name"`\n}\n\nvar (\n    tasks   = []Task{{ID: 1, Name: "学习Go"}}\n    mu      sync.Mutex\n    nextID  = 2\n)\n\nfunc getTasks(w http.ResponseWriter, r *http.Request) {\n    mu.Lock()\n    defer mu.Unlock()\n    w.Header().Set("Content-Type", "application/json")\n    json.NewEncoder(w).Encode(tasks)\n}\n\nfunc createTask(w http.ResponseWriter, r *http.Request) {\n    var task Task\n    if err := json.NewDecoder(r.Body).Decode(&task); err != nil {\n        http.Error(w, err.Error(), http.StatusBadRequest)\n        return\n    }\n    mu.Lock()\n    task.ID = nextID\n    nextID++\n    tasks = append(tasks, task)\n    mu.Unlock()\n    w.WriteHeader(http.StatusCreated)\n    json.NewEncoder(w).Encode(task)\n}\n\nfunc main() {\n    http.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) {\n        switch r.Method {\n        case http.MethodGet:\n            getTasks(w, r)\n        case http.MethodPost:\n            createTask(w, r)\n        default:\n            http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)\n        }\n    })\n    log.Println("REST API已启动,端口 :8080")\n    log.Fatal(http.ListenAndServe(":8080", nil))\n}\n
\n\n

Go中REST的优点:

\n
    \n
  • 简单且可预测——每个端点返回固定的数据结构
  • \n
  • 通过HTTP头实现出色的缓存能力
  • \n
  • 广泛的工具支持(Swagger、Postman)
  • \n
\n\n

缺点:数据过度获取和获取不足。如果客户端只需要任务名称,它仍然会收到完整的JSON。

\n\n

Go语言中的GraphQL:灵活的查询

\n\n

GraphQL解决了数据冗余的问题。客户端可以自行决定需要哪些字段。Go社区提供了强大的gqlgen库,它可以根据模式生成代码。

\n\n

使用gqlgen的GraphQL服务器示例

\n\n

首先,定义schema.graphql模式:

\n\n
type Task {\n    id: ID!\n    name: String!\n}\n\ntype Query {\n    tasks: [Task!]!\n}\n\ntype Mutation {\n    createTask(name: String!): Task!\n}\n
\n\n

现在,运行代码生成并编写Go解析器:

\n\n
package main\n\nimport (\n    "log"\n    "net/http"\n    "github.com/99designs/gqlgen/graphql/handler"\n    "github.com/99designs/gqlgen/graphql/playground"\n)\n\n// 假设已生成代码\ntype Resolver struct {\n    tasks []Task\n    mu    sync.Mutex\n}\n\nfunc (r *Resolver) Tasks(ctx context.Context) ([]Task, error) {\n    r.mu.Lock()\n    defer r.mu.Unlock()\n    return r.tasks, nil\n}\n\nfunc (r *Resolver) CreateTask(ctx context.Context, name string) (*Task, error) {\n    r.mu.Lock()\n    defer r.mu.Unlock()\n                

博客

书籍推荐