Golang工程结构最佳实践
# 一、前言
学习一门语言的语法,我们往往只需要在一个文件中进行编码,甚至连IDE都不需要,一个简单的编辑器,然后通过命令行即可进行编译、运行。
而我们一旦需要使用到数据库访问或者提供web服务的时候,单个文件就变得力不从心了。
就说数据库访问,就涉及到解析数据库协议,远程通信,甚至为了提高性能,还会用到池化技术,这些能力显然是通用的,在开开源仓库中,早已有人造好了相关的轮子,我们只需要复用其代码即可。
对于复用代码,我们能想到的最简单粗暴的方式可能便是将其源代码拷贝到我们的工程当中。
当然,这对于成熟的软件工程领域,这显然是非常原始的做法,现在主流的方法是采用包管理工具
# 待办事项
- [ ] 区分kit工程与可运行工程
- [ ] 解析主流go架构
- [ ] 解析对比主流建模
架构: https://github.com/go-kratos/kratos
# 二、Golang的包管理
在Java中,我们使用的包管理工具可以是Maven,也可以是Gradle;在JavaScript中,一般使用npm、yarn后者pnpm;对于Rust,则使用的是Cargo。
而我们今天的主角Golang,也有自己的包管理工具。
相比于其他语言的包管理工具,Golang的包管理工具则是被开发者们诟病已久。Golang官方曾多次对其包管理工具进行过改进和优化,下面我们来看看Go的包管理工具演进历史。
Go 1.14 Go Modules 终于可以投入生产了
Go从1.14版本开始,就是用了最新的Go Modules作为包管理工具。
# 2.2 如何发布公共组件
# 2.3 Go如何使用私有仓库模块
# 三、主流工程结构
https://github.com/golang-standards/project-layout
整洁架构: https://github.com/evrone/go-clean-template
# 3.1 K8S
# 3.2 Docker
# 3.3 Prometheus
# 3.4 Grafana Loki
https://github.com/etcd-io/etcd
https://github.com/gogs/gogs
https://github.com/grafana/grafana
https://github.com/gin-gonic/gin
https://github.com/kubernetes/kubernetes
https://github.com/minio/minio
https://github.com/pingcap/tidb
# 四、主流工程结构总结
# 4.1 /cmd
这里放的是打包引用程序的入口,也就是包含main函数文件的地方。
熟悉Java的同学,可以把它当做@SpringBoot注解使用的地方,也就是整个应用的入口。
与Java不同,Java如果需要提供不同的main入口,那么是需要创建不同的模块,在pom中指定启动类。 Go只需要把main函数放在不同文件下,并且package名字为main,那么就可以通过打包命令选择不同的入口文件而打包为不同的应用程序了。
# 4.2 /internal
这个目录比较特别,这个是Go编译器内置的一个特殊目录,
# 4.3 /pkg
注意,这个目录是具有一定争议的,虽然有很多流行的项目都使用这种目录结构,但是也有不少社区并不喜欢。
这个目录其实是社区相对internal建立的,目的是显示的表名这个目录下的代码,可以被第三方安全的引入
# 五、最佳实践
- root
- app
- moduleName
- modle
- api
- service
- moduleName
- boot
- middleware
- logger
- cmd
- main.go
- go.sum
- app
解析
- cmd: 该目录一般用于放命令行相关工具
- middleware,这儿一般存放公共模块,并且可以被其他项目所使用的部分
# 5.1 /cmd
这里放的是打包引用程序的入口,也就是包含main函数文件的地方。
熟悉Java的同学,可以把它当做@SpringBoot注解使用的地方,也就是整个应用的入口。
与Java不同,Java如果需要提供不同的main入口,那么是需要创建不同的模块,在pom中指定启动类。 Go只需要把main函数放在不同文件下,并且package名字为main,那么就可以通过打包命令选择不同的入口文件而打包为不同的应用程序了。
# 5.2 /internal
这个目录比较特别,这个是Go编译器内置的一个特殊目录,
# 5.3 /pkg
注意,这个目录是具有一定争议的,虽然有很多流行的项目都使用这种目录结构,但是也有不少社区并不喜欢。
这个目录其实是社区相对internal建立的,目的是显示的表名这个目录下的代码,可以被第三方安全的引入
# 六、模板工具
对于Java开发者来说,想必对SpringBoot的工程模板非常熟悉,在官方网页,只需要输入项目名称,选择基础依赖,便可以自动声场好一个项目基本框架。
对于使用npm的JavaScript开发者来说,在模板工程方面做得则更加出色,只需要简单一行命令即可通过模板工程来初始化项目。 其出色的地方更在于,开发者们为npm提供大量的工程模板,有TypeScript有Vue的,有ELementUI的,有TailweendCss的,还有Electron的,自己搭建模板工程也是非常之方便。
在Go中,目前还没有比较好的模板工具和生态,刚好趁着学习Go的机会,我们借此就自己造一个简单的模板工具,其目标就是只需要一条命令行即可初始化一个简单工程。
后面我们有复杂的需求,还可以实现比如创建DDD工程模板。