Go 项目结构

@ref:


一个常见的 Go 应用项目布局,通常有如下结构:

- my-go-project
|- cmd/
|- pkg/
|- internal/
|-biz/
|-data/
|-service
|- go.mod
|- go.sum
|- Makefile

cmd

cmd 包是项目的主干,是编译构建的入口,main 文件通常放置在此处。需要注意的是,cmd 中的代码应该尽量「保持简洁」,main 函数中可能仅仅是参数初始化、配置加载、服务启动、关闭操作。
一个典型的 cmd 包的目录结构如下所示

- cmd
- demo1
- main.go
- demo2
- main.go

pkg

pkg 中存放的是可供项目内部/外部所使用的公共性代码,例如:用来连接第三方服务的 client 代码等。也有部分项目将该包命名为 lib

- pkg
- cache
- redis
- memcache
- conf
- dsn
- paladin

internal

internal 包主要用处在于提供一个项目级别的代码保护方式,存放在其中的代码仅供项目内部使用。具体使用的规则是:…/a/b/c/internal/d/e/f 仅仅可以被…/a/b/c下的目录导入,…/a/b/g则不允许。internal 是 Go 1.4 版本中引入的特性,更多信息可以参考https://go.dev/doc/go1.4#internalpackages

- internal
- demo1
- biz
- data
- service

internal: 是为了避免有同业务下有人跨目录引用了内部的 biz、 data、service 等内部 struct。
• biz:业务逻辑的组装层,类似DDD的domain层,data类似DDD 的 repo,repo 接口在这里定义,使用依赖倒置的原则。
• data:业务数据访问,包含cache、db等封装,实现了biz的repo 接口。我们可能会把 data 与 dao 混淆在一起,data 偏重业务的含义, 它所要做的是将领域对象重新拿出来,我们去掉了 DDD 的 infra 层。
• service:实现了api定义的服务层,类似DDD的application层,处理 DTO 到 biz 领域实体的转换(DTO -> DO),同时协同各类 biz 交互, 但是不应处理复杂逻辑。

go.mod

go.mod 与 go.sum 是采用 go modules 进行依赖管理所生成的配置文件。go modules 是 Go 1.11 版本中引入的版本管理功能,目前已经是 go 依赖管理的主流方式,所以此处不再讨论 vendor,dep 等依赖管理方式所生成的目录。

Makefile

Makefile 文件通常存放项目的编译部署脚本。Go 的编译命令虽然简单,但总是手写命令还是效率低下,因此使用 Makefile 写编译部署脚本是工程实践中常见的方式。

kit

工具包项目通常也叫 kit 项目,包含公司的公共依赖库,在 https://github.com/ardanlabs/kit 中给出了一个 kit 项目布局示例:

github.com/ardanlabs/kit
├── CONTRIBUTORS
├── LICENSE
├── README.md
├── cfg/
├── examples/
├── log/
├── pool/
├── tcp/
├── timezone/
├── udp/
└── web/

kit 项目有以下几个特点:

  • (1)建议公司只有「一个」 kit 项目,kit 包含的是供公司多个项目使用的基础库,提供非常具体但是基本的功能。
  • (2)建议 kit 项目不要依赖第三方库版本,即 kit 中不要包含 vendor, go modules 等版本管理信息。kit 本质是基础工具包,如果内部含有 vendor 等版本管理,那么就要随着第三方库的更新而不断更新,导致上层依赖 kit 的应用也得随之更新,变更代价很大。