本文首发地址:jianghushinian.cn/2023/02/25/…
Go 言语作为一门高效、简练、并发安全的言语,越来越受到开发者们的喜爱,特别是在 Web 开发及云原生范畴。而关于一个大型的 Go Web 项目而言,一个优异的目录结构规划是必不可少的。它可以协助咱们更好地安排代码、削减冗余、进步可保护性和可扩展性。在本文中,咱们将评论怎么规划一个优异的 Go Web 项目目录结构。
基本准则
在开始规划项目目录结构之前,咱们需求先了解一些规划目录的基本准则:
-
可读性和可保护性:规划目录结构应该易于阅览和保护,目录称号要简练、明晰,最好能达到望文生义的效果。
-
可扩展性和模块化:规划目录结构应该易于扩展和模块化,随着时间的推移,项目会不断变大,项意图目录结构应该可以很容易支撑这种变化。
-
标准性和共同性:规划目录结构应该遵循标准和共同性,如无特殊情况,目录称号最好共同运用奇数方法(特殊情况可以打破,如
/docs
、/examples
)。
Go 项目标准布局
前期的 Go 项目目录结构规划形形色色,由于大多数 Go 开发者都有其他编程言语根底,比方 Java、Python 等,这些开发者在规划 Go 项目时,目录结构往往会携带一些其他编程言语、框架所惯用的风格。
但许多情况下,直接套用其他编程言语风格的目录所规划出来的 Go 项目都会有许多不合理之处,为了改变现状,慢慢的 Go 言语社区诞生了许多更契合 Go 哲学的项目目录风格。而这其间,最著名的项目当属 golang-standards/project-layout。
golang-standards/project-layout
是一个 Go 社区保护的 Go 项目目录结构标准,它的目标是供给一种共同性的、易于了解和运用的目录结构,从而协助开发者更好地安排和办理自己的代码。
该项意图目录结构基于功能和约定进行安排,经过供给一种标准化的目录结构,可以使得不同的项目之间具有共同的代码安排方法,便于开发者了解和运用。
该项意图目录结构包括以下几个部分:
Go 应用程序相关目录
/cmd
这个目录首要担任程序的发动、初始化、中止等功能,故首要包括项意图入口文件 main.go
,假如一个项目有多个组件,则可以寄存多个组件的 main.go
,例如:
cmd
├── ctl
│ └── main.go
├── server
│ └── main.go
└── task
└── main.go
不要在这个目录中放太多的代码,更不要放事务逻辑代码,保持整齐。
/internal
寄存项意图内部私有代码和库,不允许在项目外部运用。同时这也是 Go 在编译时强制履行的校验规矩,假如在其他项目中导入 internal
目录下的内容,Go(1.19) 在编译时会得到如下错误:
use of internal package xxx not allowed
注:
xxx
为包括internal
的包途径
在项意图目录树中的恣意方位都可以有 internal
目录,而不仅仅是在尖端目录中。
在 /internal
内部可以添加额外的包结构来区别组件间同享和私有的内部代码:
internal
├── app
│ ├── ctl
│ ├── server
│ └── task
└── pkg
其间 /internal/app
下寄存各个组件的逻辑代码,/internal/pkg
下寄存各组件间的同享代码。
/pkg
包括可导出的公共库,可以被其他项目引证。这意味着此目录下的代码可以被导入任何其他项目,被当作库程序来运用,所以将代码放到此目录前要慎重考虑,不要将私有代码放到此目录下。
Travis Jeffery 撰写了一篇文章解说了 pkg
和 internal
目录运用主张,你可以进一步了解学习。
/configs
此目录寄存装备文件模板或默许装备。
前文讲规划项目目录的基本准则时说到目录名最好运用奇数方法,不过由于运用 configs
来寄存装备已经是约定俗成的事实标准,故此目录称号可以打破这项规划准则。
/test
可以用来寄存 e2e 测试和测试数据等。
关于较大的项目,有一个数据子目录更好一些。例如,假如需求 Go 在编译时忽略目录中的内容,则可以运用 /test/data
或 /test/testdata
这样的目录称号。
别的 Go 还会忽略以 .
或 _
最初的目录或文件,因而可以更具灵活性的来命名测试数据目录。
deployments
用来寄存 IaaS、PaaS 体系和容器编列布置所需求的装备及模板(如:Docker-Compose,Kubernetes/Helm,Mesos,Terraform,Bosh)。
假如你的项目作为 Kubernetes 生态中的一员或运用 Kubernetes 布置,则主张命名为 /deploy
,更加契合 Kubernetes 社区风格。
/third_party
外部辅助东西目录,fork 的代码和其他第三方东西(例如 Swagger UI)。比方咱们修改了某个开源的第三方项意图代码,使其满意当时项意图运用需求,就可以将修改后的代码放到 /third_party/fork
目录下进行保护。
/web
假如你打算在项目目录下包括配套的前端程序代码,则可以寄存到此目录。首要包括静态资源、前端代码、路由等。
假如你的项目仅供给 RESTful API,且前后端程序需求分开独立保护,则可以不需求此目录,主张将前端代码作为一个独立的项目存在。
项目办理相关目录
/init
包括体系初始化(systemd、upstart、sysv)和进程办理(runit、supervisord)等装备。这在非容器化布置的项目中非常有用。
别的还可以包括初始化代码,如数据库搬迁、缓存初始化等。
/scripts
寄存用于履行各种构建、安装、分析等操作的脚本。
根文件 /Makefile
可以引证这些脚本,使其变得更小、更易于保护。
/build
寄存程序构建和持续集成相关的文件。例如:
运用 /build/package
目录来寄存云(AMI),容器(Docker),操作体系(deb,rpm,pkg)软件包装备和脚本。
运用 /build/ci
目录来寄存 CI(travis、circle、drone)装备文件和脚本。
/tools
此项意图支持东西。这些东西可以从 /pkg
和 /internal
目录导入代码。
/assets
项目运用的其他资源 (Image、CSS、JavaScript、SQL 文件等)。
/githooks
Git 相关的钩子寄存目录。
项目文档相关目录
/api
当时项目对外露出的 API 文档,如 OpenAPI/Swagger 标准文档、JSON Schema 文件、ProtoBuf 界说文件等。
api
└── openapi
└── openapi.yaml
/docs
规划、开发和用户文档等(除 godoc 生成的文档)。
/examples
应用程序或公共库的示例。降低运用者的上手难度。
不主张运用的目录
/src
一些有 Java 或 Python 开发经验的开发者习气在项目中规划一个 /src
目录,但在 Go 言语中这是不引荐的做法。
前期的 Go 言语的项目都会被放置到 $GOPATH/src
目录下,假如项目中再有一个 /src
目录,那么项目终究的寄存的途径就显得比较奇怪:
$GOPATH/src/your_project/src/your_code.go
因而,请不要在一个 Go 项目中规划 /src
目录。
一些放在项目根目录下的文件
/README.md
README.md
是学习并运用项意图入口,是让用户了解项意图第一手资料。一个项意图 README.md
一般包括项目称号和简介、安装说明、运用说明、奉献方法、版权和答应等。
GitHub 也会默许解析 README.md
文件并渲染成 HTML 文档。
/Makefile
Makefile
是一个老牌的项目办理东西,主张在 Go 项目中都集成它。Makefile
语法可以参阅 跟我一起写 Makefile
。
/CHANGELOG
用于寄存项意图更新记录,如版本号、作者、更新内容等。假如嫌麻烦,还可以运用 git-chglog 或相似东西主动生成。
/CONTRIBUTING.md
假如你的项目是开源项目,则主张包括 /CONTRIBUTING.md
文件,用来说明怎么奉献代码、项目标准等,让第三方开发者更容易参与进来。
/LICENSE
开源项目必定要包括 /LICENSE
,即开源答应证。没有开源答应证的项目,严格来讲不叫开源项目,怎么挑选开源答应证可以参阅我的另一篇文章 开源协议简介。
总结
经过上面的解说,终究咱们得到的项目目录结构如下:
project
├── CHANGELOG
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── api
│ └── openapi
│ └── openapi.yaml
├── assets
├── build
├── cmd
│ ├── ctl
│ │ └── main.go
│ ├── server
│ │ └── main.go
│ └── task
│ └── main.go
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── init
├── internal
│ ├── app
│ │ ├── ctl
│ │ ├── server
│ │ └── task
│ └── pkg
├── pkg
├── scripts
├── test
├── third_party
├── tools
└── web
此目录结构首要参阅 golang-standards/project-layout
项目,和一些我自己的思考,终究总结出来。
经过运用以上供给的项目目录结构,可以协助开发者更好地办理和安排自己的代码,进步代码的可保护性和可扩展性。
以上介绍的目录结构比较合适中大型项目,假如你的项目比较小,则可以只运用 /cmd
、/internal
、/configs
等几个少数目录,其他目录根据需求再来创立。假如你的项目满足小,乃至不需求什么目录,直接采用平铺式代码结构(将所有文件都放在项目根目录下)即可。
别的,随着技能的不断迭代发展,如 DDD 正在流行起来,Go 社区对项目目录结构的探究也仍在持续,在可预见的未来,一个优异的 Go Web 项目目录结构的界说必定会被更新,等待下次可以分享更优异的目录结构规划。
P.S.
本文部分内容由 ChatGPT 生成,体会科技乐趣 :)。
参阅
github.com/golang-stan…
github.com/golang-stan…
github.com/danceyoung/…
travisjeffery.com/b/2019/11/i…