基本要求
对项目结构做一些基本要求:
- 功能明确:每一层的功能明确,在编写业务逻辑时具有一定的辨识度,能够轻松进行分层
- 全面:项目结构中包含研发过程中的主要功能,包括文档、脚本、测试、工具等
- 可扩展性:当项目业务逻辑更复杂、规模变大时,能够支持扩展
- 可预测性:随着业务逻辑复杂,项目结构变大,但在结构扩展的同时应该保持结构不需要发生大的变动
逻辑架构
按开发—测试—部署三个阶段以及项目管理、文档,总体如下:
Go 应用
├── 开发阶段
│ ├── 前端 /web
│ └── 后端
│ ├── /cmd
│ ├── /internal
│ ├── /pkg
│ ├── /vendor
│ └── /third_party
├── 测试阶段
│ └── /test
└── 部署阶段
├── /configs
├── /deployments
└── /init
项目周期管理
├── /Makefile
├── /build
├── /website
├── /tools
├── /githooks
└── /assets
文档
├── /README.md
├── /docs
├── /LICENSE
├── /api
└── /CONTRIBUTING.md
目录说明
前端
/web —— 前端代码存放目录。
后端
/cmd
- 存放当前项目的可执行文件
cmd目录下的每一个子目录名称都应该匹配可执行文件。例如,把组件main函数所在的文件夹统一放在/cmd目录下- 不要在
/cmd目录中放置太多代码,我们应该将公有代码放置到/pkg中,将私有代码放置到/internal中,并在/cmd中引入这些包,保证 main 函数中的代码尽可能简单和少
/internal
- 存放私有应用和库代码
- 如果一些代码你不希望被其他项目/库导入,可以放至
/internal目录下。这在代码编译阶段就会被限制,该目录下的代码不可被外部访问到
一般有以下子目录:
/router路由/application存放命令与查询/command/query
/middleware中间件/model模型定义/repository仓储层,封装数据库操作/response响应/errmsg错误处理
在 /internal 目录下应存放每个组件的源码目录。当项目变大、组件增多时,可以将新增的组件代码继续存放到 /internal 下。
internal 目录并不局限在根目录,在各级子目录中也可以有 internal 子目录,同样起到作用。
/pkg
- 存放可以被外部应用使用的代码
/pkg目录下的包可以被其他项目引用,所以将代码放入该目录时候一定要慎重- 在非根目录下也可以加入
pkg目录。很多项目会在internal目录下加入pkg表示内部共享包库
个人建议:一开始将所有的共享代码存放在 /internal/pkg 目录下,当确认可以对外开放时,再转至到根目录的 /pkg 目录下。
/vendor
- 存放项目依赖
- 可以通过命令
go mod vendor创建 - 如果创建的是一个 Go 库,不要提交
vendor依赖包
/third_party
- 存放一些第三方的资源工具文件
测试
/test
- 存放整个应用的测试、测试数据及一些集成测试等
- 相较于单元测试放在每个 Go 文件对应的目录下,
test目录偏向于整体 - 在某些子项目内也会有局部的测试放在子项目的
test中 - 需要 Go 忽略该目录中的内容,可以使用
/test/data或/test/testdata目录 - Go 会忽略
.或_开头的目录或文件
部署
/config 或 /configs
- 配置文件或者配置文件模板所在的文件夹
- 配置中不能携带敏感信息,可用占位符代替
/init
- 存放初始化系统和进程管理配置文件
/deployments 或 /deploy
- 存放 IaaS、PaaS 系统和容器编排部署配置和模板
文档
/README.md
项目的 README 文件一般包含:项目的介绍、功能、快速安装和使用指引、详细的文档链接以及开发指引。
/docs
各类文档所在目录。存放设计文档、开发文档和用户文档等。
/LICENSE
版权文件。可以是私有的,也可以是开源的。
常用的开源协议:Apache 2.0、MIT、BSD、GPL、Mozilla、LGPL。
/api
当前项目对外提供的各种不同类型的 API 接口定义文件。其中可能包含类似 OpenAPI、Swagger 的目录,包含了当前项目对外提供和依赖的所有 API 文件。
/CONTRIBUTING.md
说明如何贡献代码,如何开源协同:
- 规范协同流程
- 降低第三方开发者贡献代码的难度
项目管理
/Makefile
对项目进行管理。执行静态代码检查、单元测试、编译等功能。
/build
存放安装包和持续集成相关的文件。
/website
如果不使用 GitHub Pages,则在这里放置项目的网站数据。
/assets
项目使用的其他资源(如图片等)。
/tools
存放这个项目的支持工具。这些工具可导入来自 /pkg 和 /internal 目录的代码。
/githooks
Git 钩子。
小结
这个结构不是”必须遵守的教条”,而是一份可预测的默认排布——让新加入的人打开仓库就能猜到”我要改的东西大概在哪个目录”,省去阅读项目文档的时间。
对于小型服务,可以只保留 /cmd、/internal、/pkg、/configs、/deployments 这五个即可,其他等到真正需要时再加。不要为了结构完整而制造空目录,那反而增加认知负担。
