如何编写Go API:终极指南 - Jonny Langefeld
文章目录
“TIL”(今天我了解到)是一个有趣的缩写词,意为“今天我学到了”。作为一名英语非母语者,我经常通过在线词典了解这些缩写词的含义。这个词让我意识到学习是无止境的,因此我开始撰写关于Python Flask API的博客,随后又扩展到如何编写Go API的系列文章。在这篇文章中,我将分享自己在编写高效且可用于生产的Go API过程中积累的最佳实践。
项目脚手架
以下是我推荐的项目结构布局,可以根据需要在 pkg 目录下添加更多模块:
├── go.mod
├── go.sum
├── main.go
# main.go 位于根目录,而非 /cmd 目录
├── pkg
│ ├── api# 包含所有 API 相关函数和路由
│ │ ├── api.go
│ │ ├── api_test.go
│ │ └── operations.go
│ ├── db# 数据库交互逻辑
│ │ ├── db.go
│ │ └── db_test.go
│ ├── middleware# 自定义中间件
│ │ ├── context.go
│ │ └── logger.go
│ └── types# 类型定义单独存放
│ └── types.go
├── readme.md
└── tools.go# 通过 go.mod 管理工具版本
在解决项目结构问题后,我们可以进一步探讨 main.go 文件的实现。
工具.go 模式
通过 Go 模块管理工具依赖关系是一种非常高效的方式。它不仅可以固定依赖版本,还能将其包含在供应商目录中。Marco Franssen 的博客对此有详细探讨。
带 pflag 的命令行标志
使用 pflag 可以轻松处理命令行标志,并提供内置帮助功能。例如:
$ go-api -h
用法:
-a, --address string API 监听的地址,格式为 "主机:端口"(默认值为 ":8080")
使用 zap 进行结构化日志记录
借助 zap,我们可以生成清晰且结构化的日志输出,便于调试和监控。
优雅的退出
在 API 关闭时,执行清理任务是一个良好的实践。通过在程序启动时创建一个通道监听特定事件(如键盘中断),可以实现优雅的退出。例如:
// 示例代码
启动时的日志版本
在调试日志中记录代码版本信息非常有用。通过在 main.go 文件中注入未设置的 version 变量,并在构建命令中设置该变量,可以实现这一功能:
var version string
// 在 main 函数中使用 version
在独立包中定义类型
将类型定义为可复用的结构体(struct),不仅有助于代码组织,还能方便其他开发者直接导入这些类型。例如,在 pkg/types/types.go 中定义类型:
type ExampleType struct {
Field string json:"field"
}
使用 chi 作为 HTTP 框架
chi 是一个轻量级的 HTTP 路由框架,支持嵌套路由和中间件。以下是一个示例请求树,用于处理商店的商品和订单:
/api
/products
/orders
定制中间件
自定义中间件可以为 API 处理逻辑注入额外功能。例如,我们可以创建一个中间件,将数据库对象注入到请求上下文中,从而避免重复访问数据库:
func ArticleMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 从数据库中获取文章对象并注入上下文
ctx := context.WithValue(r.Context(), "article", article)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
分页
关于分页的详细实现,请参考相关博客文章。
与 gorm 的数据库集成
通过自定义客户端接口封装 gorm 客户端,可以简化数据库操作并提高测试的可维护性。例如:
type DBClient interface {
Connect() error
// 其他数据库操作方法
}
使用 dockertest 进行数据库集成测试
为了确保测试环境与生产环境一致,可以使用 dockertest 创建短生命周期的数据库容器。这种方法不仅适用于本地开发,也能在 CI 系统中稳定运行。
API 与 gomock 的集成测试
通过 gomock 创建模拟接口,可以在不依赖实际数据库的情况下测试 API。例如:
mockDB := gomock.NewController(t)
使用 http swagger 将文档作为代码
通过 Swagger UI,可以为 API 提供交互式文档。启动后,访问 <http://localhost:8080/swagger> 即可查看完整的 API 文档:

分阶段的 Dockerfile
使用多阶段构建 Docker 镜像,可以优化构建过程。例如:
FROM golang:1.17 AS builder
WORKDIR /app
COPY . .
RUN go build -o go-api
FROM gcr.io/distroless/base
COPY --from=builder /app/go-api /bin/go-api
ENTRYPOINT ["/bin/go-api"]
通过以上实践,我们可以构建一个高效、可维护且适用于生产环境的 Go API。
原文链接: https://jonnylangefeld.com/blog/how-to-write-a-go-api-the-ultimate-guide
最新文章
- 增强API安全性:使用OPA和Kong Gateway进行细粒度访问控制
- 如何免费调用有道翻译API实现多语言翻译
- 公司logo获取服务:如何让企业自动化生成Logo变得轻松简单?
- 了解和使用REST API
- 为什么API开发对现代应用至关重要?
- 如何利用Apache APISIX实现高效的API认证与鉴权:全面解析主流认证方式
- 医疗保健领域中api解决方案的优势与劣势
- 如何获取腾讯AI开放平台 API Key 密钥(分步指南)
- 如何使用Flask-RESTX构建和文档化RESTful API
- API类型:详解与图示 – Kodezi博客
- 百度文心一言API使用指南:非技术人员入门教程
- 如何获取腾讯AI开放平台 API Key 密钥(分步指南)