[译] Go项目结构设计最佳实践

jmx

关于Go项目的结构设计,推荐先观看 Kat Zien 关于Go项目结构设计的演讲:https://www.youtube.com/watch?v=oL6JBUk6tj0

本文内容整理自 Elliot Forbes: Go Project Structure Best Practices

以下为部分译文:

Go应用程序应该遵循的项目结构是一个有争议的主题,因为Go项目结构并没有统一规范。很多人认为应该遵循 golang-standards / project-layout 结构,但是随着Go Modules成为处理Go依赖关系的标准,这种结构开始面临挑战。按照传统结构,您会发现项目结构中的某些包并没有访问权限,如 internalpkg,而一旦要处理起来也是非常的棘手。

在构建应用程序时,没有一劳永逸的方法。随着应用程序的发展,项目结构也在不断发展。

在本文中,我将介绍在构建Go应用程序时可以选择的项目结构。

小型应用 - 平面结构

这种项目结构清晰简单,不需要花费太多的时间去整理项目结构,同时作为开发人员,可以尽可能的专注于完成目标功能。

1
2
3
4
5
6
application/
- main.go
- main_test.go
- utils.go
- utils_test.go
- ...

这种项目结构适用于以下应用:

  • 微服务 - 实现单一功能的应用程序
  • 小型工具库 - 用于完成少数任务的命令行工具或小型工具库

应用例子

一些使用这种项目结构的例子:

中大型应用 - 模块化

随着项目规模变大,复杂性增长,您很快就会发现它开始超出平面结构,这时就应该开始考虑模块化了。

以网站的REST API为例,假设该REST API需要提供注册和登录功能,以及需要类似CRUD方式处理用户文章的功能。这时我们需要考虑将应用程序按照功能分组,并尽可能的把不同组件之间共享的核心逻辑放到项目的共享包中。

此时项目结构可能会变成这样:

1
2
3
4
5
6
7
8
9
10
rest-api/
- main.go
- user/
- - user.go
- - login.go
- - registration.go
- articles/
- - articles.go
- utils/
- - common_utils.go

应用例子

  • google / go-cloud - 这是采用此结构的项目中一个很好的例子。项目被分解为每个IAAS云提供商的程序包,并且每个程序包都包含与该特定云提供商有关的所有代码。
  • hashicorp / consul - 这是使用模块化大型项目中另一个很好的例子。
  • ipfs / go-ipfs - 全局版本化的对等文件系统
  • gohugoio / hugo - 快速灵活的静态站点生成器

成熟的应用

您一定会看到符合旧结构的项目,但这些项目是属于Go早期版本的产品。

如 Hashicorp 的 Terraform 或 Google 自己的 Kubernetes 之类的大型应用程序往往会保留旧结构,因为这些项目是$GOPATH统治时代的产品,您会看到它们仍然具有internalpkg文件夹,其中封装了项目的某些内部工作。

这种结构项目运行得非常好,使开发人员能够为开发社区带来不可思议的价值,但我认为,随着Go Modules开始变得越来越流行,我们将会看到这些应用程序从传统的结构迁移到新的结构。

拆分项目

在特定的时间点后,将项目中的某些部分从原项目中拆分出来,创建新的项目独立维护,可能是非常有意义的。虽然可能导致管理项目需要使用额外的开销,但是这也意味着对想要贡献和帮助项目的新手来说更加友好。

总结

这些是我日常工作中的开发经验,希望本文对您的开发工作有所帮助,并在您开始为下一个Go项目建模时提供一些想法!