go项目标准化工程结构解析
目录
1. Go标准项目结构目录
/cmd
/internal
/pkg
/API
/WEB
/configs
/scripts
/build
/deployments
/test
/docs
2. Go标准项目结构示例解析
项目整体结构
/cmd 项目启动目录结构
internal私有目录结构
平时我们学习go或者是写一些小的demo的时候,可能直接在工程下建一个main.go的文件就直接开始。但是如果想做一个长期维护或者正式应用的项目时,我们还是要按一定的规范来设计项目结构,不然随着项目越来越复杂,代码越来越多,依赖也越来复杂,到时候项目可能都没法进行维护了。这时就需要引入合理的项目工程结构了。
1. Go项目结构目录
go官方并没有定义go项目工程化的项目结构,但是网上有一个提供参考的Standard Go Project Layout的结构
参考地址:https://github.com/golang-standards/project-layout/blob/master/README_zh.md
虽然不是官方标准,但是基本上已经被大家接受了。首先我们大概分析一下该项目的结构
/cmd
本项目的主干。 cmd目录下的每个应用程序的目录名应该与你想要的可执行文件的名称相匹配,比如:
/cmd/job: 定时任务或从消息队列订阅的异步任务的命令入口
/cmd/service:微服务启动的入口
说明:
该目录相当于应用启动入口,通常有一个main的目录调用,通常不会在这个目录中放置太多代码。
通常我们将cobra的启动的命令放在该目录,用来做项目启动,不同的子命令可以对应不同的启动项目。
而实际执行的业务部分代码从 /internal 和 /pkg 目录导入和调用代码。
如果你认为代码可以导入并在其他项目中使用,那么它应该位于 /pkg 目录中
如果代码不是可重用的,或者你不希望其他人重用它,请将该代码放到 /internal目录中
/internal
私有应用程序和库代码。这是你不希望其他人在其应用程序或库中导入代码。
这个布局模式是由 Go 编译器本身执行的。 参考链接: https://golang.org/doc/go1.4#internalpackages。 因此要注意,internal不局限于顶级 `internal` 目录。在项目树的任何级别上都可以有多个内部目录。
你可以选择向 internal 包中添加一些额外的结构,以分隔共享和非共享的内部代码。比如内部共享的应用包
/internal/app: 你的实际应用程序代码可以放在该目录下,比如job项目结构/internal/app/job,我们可以将具体的job业务代码放到该目录下
/internal/pkg: 你可以将内部共享包放到该目录下,比如我们将内部配置的配置包(internal/pkg/config、数据库配置(internal/pkg/database)、自己封装的日志包(internal/pkg/log)放到该目录下。
/pkg
外部应用可以使用的库代码(比如 /pkg/netutil)。其它项目想要导入他们,然后正常的工作,所以将内容放到这里请三思。
注意 /internal 是更好的方式来确保你的私有代码不被别人使用,因为它是 Go 强制执行的。
/pkg 是明确传达给别人这是公开的代码可被安全使用的好方法。
Travis Jeffery 写的I'll take pkg over internal 文章很好的说明了 /internal和 /pkg 以及何时使用它们。
/API
OpenAPI/Swagger 规范,协议定义文件,JSON/Proto模式文件。
/WEB
特定于 Web 应用程序的组件: 静态 Web资源、服务器端模板和 SPAs。
/configs
配置文件模板或默认配置。将你的 confd或 consul-template模板文件放在这里。
/scripts
执行各种构建、安装、分析等操作的脚本。
这些脚本保持了根级别的 Makefile 变得小而简单(例如, https://github.com/hashicorp/terraform/blob/master/Makefile)
/build
打包和持续集成。
将你的云( AMI )、容器( Docker )、操作系统( deb、rpm、pkg )包配置和脚本放在 /build/package目录下。
将你的 CI (travis、circle、drone)配置和脚本放在 /build/ci 目录中。请注意,有些 CI 工具(例如 Travis CI)对配置文件的位置非常挑剔。尝试将配置文件放在 /build/ci目录中,将它们链接到 CI 工具期望它们的位置(如果可能的话)。
/deployments
IaaS、PaaS、系统和容器编排部署配置和模板(docker-compose、kubernetes/helm、mesos、terraform、bosh)。注意,在一些存储库中(特别是使用 kubernetes 部署的应用程序),这个目录被称为 /deploy。
/test
额外的外部测试应用程序和测试数据。你可以随时根据需求构造 /test 目录。对于较大的项目,有一个数据子目录是有意义的
/docs
设计和用户文档(除了 godoc 生成的文档之外)。
2. Go标准项目结构示例解析
针对以上的Standard Go Project Layout的结构,网上有一个实际对应的使用示例工程项目,具体示例项目参考下面链接:
参考链接:GitHub - sdgmf/go-project-sample: Introduce the best practice experience of Go project with a complete project example.通过一个完整的项目示例介绍Go语言项目的最佳实践经验.
如果想要按照该项目结构来创建应用,可以直接将代码拉取下来,然后更改相应部分业务即可。
项目整体结构
我们看下示例项目的实际目录构成:
├── LICENSE
├── Makefile // makefile打包文件
├── README.md
├── api // 接口协议定义,proto文件
│ └── proto
├── build // 项目构建目录
│ ├── details
│ ├── products
│ ├── ratings
│ └── reviews
├── cmd // 项目启动目录入口,这里有4个微服务
│ ├── details
│ ├── products
│ ├── ratings
│ └── reviews
├── configs // 配置文件目录
│ ├── details.yml
│ ├── grafana
│ ├── products.yml
│ ├── prometheus
│ ├── ratings.yml
│ └── reviews.yml
├── deployments // 部署文件目录
│ └── docker-compose.yml
├── doc // 文档目录
│ └── images
├── go.mod
├── go.sum
├── internal // 内部文件
│ ├── app
│ └── pkg
├── mocks
│ ├── DetailsClient.go
│ ├── DetailsRepository.go
│ ├── DetailsServer.go
│ ├── DetailsService.go
│ ├── RatingsClient.go
│ ├── RatingsRepository.go
│ ├── RatingsServer.go
│ ├── RatingsService.go
│ ├── ReviewsClient.go
│ ├── ReviewsRepository.go
│ ├── ReviewsServer.go
│ └── ReviewsService.go
└── scripts // 脚本文件目录├── grafana├── products.sql├── prometheus├── wait-for└── wait-for-it.sh
这里功能实现部分主要关注的是cmd目录下的和internal目录下的。
/cmd 项目启动目录结构
cmd目录下按服务划分为details,products,ratings和reviews四个服务。 目录结构如下:
├── details
│ ├── main.go
│ ├── wire.go
│ └── wire_gen.go
├── products
│ ├── main.go
│ ├── wire.go
│ └── wire_gen.go
├── ratings
│ ├── main.go
│ ├── wire.go
│ └── wire_gen.go
└── reviews├── main.go├── wire.go└── wire_gen.go
该项目中是依赖注入的wire来管理每个模块之间的依赖注入,在cmd部分将项目配置,以及业务逻辑部分组装成应用,使用cobra可以用来管理相应的子命令来启动相应的服务。
wire的具体使用可以参考:go依赖注入--google开源库wire_CK持续成长的博客-CSDN博客
internal私有目录结构
与cmd相对对应的四个服务逻辑实现部分对应internal/app目录下的四个服务业务逻辑实现,internal/app的目录结构结构如下:
app
│
├── details
│ ├── app.go
│ ├── controllers
│ │ ├── controllers.go
│ │ ├── details.go
│ │ ├── details_test.go
│ │ ├── wire.go
│ │ └── wire_gen.go
│ ├── grpcservers
│ │ ├── details.go
│ │ ├── details_test.go
│ │ ├── servers.go
│ │ ├── wire.go
│ │ └── wire_gen.go
│ ├── repositories
│ │ ├── cover.out
│ │ ├── details.go
│ │ ├── details_test.go
│ │ ├── repositories.go
│ │ ├── wire.go
│ │ └── wire_gen.go
│ └── services
│ ├── details.go
│ ├── details_test.go
│ ├── services.go
│ ├── wire.go
│ └── wire_gen.go
├── products
│ ├── app.go
│ ├── controllers
│ │ ├── controllers.go
│ │ └── products.go
│ ├── grpcclients
│ │ ├── clients.go
│ │ ├── details.go
│ │ ├── ratings.go
│ │ └── reviews.go
│ └── services
│ ├── products.go
│ ├── products_test.go
│ ├── services.go
│ ├── wire.go
│ └── wire_gen.go
├── ratings
│ ├── app.go
│ ├── controllers
│ │ ├── controllers.go
│ │ ├── ratings.go
│ │ ├── ratings_test.go
│ │ ├── wire.go
│ │ └── wire_gen.go
│ ├── grpcservers
│ │ ├── rating.go
│ │ ├── rating_test.go
│ │ ├── servers.go
│ │ ├── wire.go
│ │ └── wire_gen.go
│ ├── repositories
│ │ ├── ratings.go
│ │ ├── ratings_test.go
│ │ ├── repositories.go
│ │ ├── wire.go
│ │ └── wire_gen.go
│ └── services
│ ├── ratings.go
│ ├── ratings_test.go
│ ├── services.go
│ ├── wire.go
│ └── wire_gen.go
└── reviews├── app.go├── controllers│ ├── controllers.go│ ├── reviews.go│ ├── reviews_test.go│ ├── wire.go│ └── wire_gen.go├── grpcservers│ ├── reviews.go│ ├── reviews_test.go│ ├── servers.go│ ├── wire.go│ └── wire_gen.go├── repositories│ ├── repositories.go│ ├── reviews.go│ ├── reviews_test.go│ ├── wire.go│ └── wire_gen.go└── services├── reviews.go├── reviews_test.go├── services.go├── wire.go└── wire_gen.go
每个服务分层为controllers,services和repositories。 controllers来管理http的请求,services实现相应部分的业务逻辑,repositories提供数据仓库,该部分也是用wire用来管理主要注入的依赖。
而internal/pkg为内部的共享的包,该结构里面包括config中配置对象一些封装和初始化,比如database,consul等,以及自己二次封装的一些内部库http, grpc, netutil等,具体的internal/pkg目录如下:
── pkg
│ ├── app
│ │ └── app.go
│ ├── config
│ │ └── config.go
│ ├── consul
│ │ └── consul.go
│ ├── database
│ │ └── database.go
│ ├── jaeger
│ │ └── jaeger.go
│ ├── log
│ │ └── log.go
│ ├── models
│ │ ├── detail.go
│ │ ├── product.go
│ │ ├── rating.go
│ │ └── review.go
│ ├── transports
│ │ ├── grpc
│ │ └── http
│ └── utils
│ └── netutil
go项目标准化工程结构解析相关推荐
- 《ArcGIS Runtime SDK for Android开发笔记》——(6)、基于Android Studio的ArcGIS Android工程结构解析...
1.前言 Android Studio 是第一个Google官方的 Android 开发环境.其他工具,例如 Eclipse,在 Android Studio 发布之前已经有了大规模的使用.为了帮助开 ...
- Radware负载均衡项目配置实战解析之四-VRRP双机配置与同步
接上一小节内容,这一节主要介绍RADWARE负载均衡实战项目中的VRRP双机配置与同步问题.radware在实际的业务与配置中,一般都会配置双机来实现冗余.无论是主用设备还是备用设备都要进行基本配置. ...
- vue router 参数_Vue.js项目开发技术解析
Vue.js项目开发技术解析 一.Vue.js实例 在一个Vue.js工程中,用于显示内容最基层的实例称之为根实例.通过该实例可以进行页面或组件的更新和显示.对于项目本身而言,无论是什么样的页面,都要 ...
- java eventbus 原理_本文为 Android 开源项目实现原理解析 EventBus 部分,从源码分析 EventBus 的实现原理...
之前太忙导致 Android 开源项目实现原理解析 一度搁浅,目前一期进行中,我也完成了 EventBus 分析的初稿,大家可以稍微看看后面会继续润色下. PS:本文直接复制 Markdown,格式有 ...
- [高光谱] 开源项目Hyperspectral-Classification Pytorch解析之main
开源项目Hyperspectral-Classification Pytorch解析之main.py 编码方式: # -*- coding: utf-8 -*- 项目简介: ""& ...
- [高光谱] GitHub开源项目Hyperspectral-Classification的解析
GitHub链接:Hyperspectral-Classification Pytorch. 画重点!!! 完整版看这里嗷:GitHub开源项目Hyperspectral-Classification ...
- Spring Boot(一):概述(5)——Spring Boot项目推荐工程结构
Spring Boot项目推荐工程结构:
- springboot项目配置视图解析器无效的问题
springboot项目配置视图解析器无效的问题 今天springboot尝试配置视图解析器的时候,如图: 一切正常,视图解析器却始终无效.后面发现问题. 在控制器的注解要使用:@Controller ...
- eclipse java转class_Eclipse中的Java项目:无法解析java.lang.Object类型。 它是从所需的.class文件间接引用的...
Eclipse中的Java项目:无法解析java.lang.Object类型. 它是从所需的.class文件间接引用的 在Eclipse中导入项目后,我收到以下错误: 无法解析java.lang.Ob ...
最新文章
- 西部985,进军北京!
- Dockerfile文件命令详解
- iPIN CEO 杨洋:AI 还未被大规模用在工作中,缺的是认知智能
- superset出现A valid API access token is required to use Mapbox data
- win10必须禁用的服务_7寸屏的迷你电脑,就算是8GB运行内存,也必须关闭的系统选项...
- 疫情相关电信诈骗涉案金额超3.51亿元,谨防这四类骗局!
- 世界地图矢量文件shp格式获取/下载方法_江仔91_新浪博客
- 1.30 fcntl函数
- C语言经典100道编程练习题
- 转:组态软件测评∣WinCC、Citect、LabVIEW、InTouch、Ingnition,你更喜欢用哪个?
- Typora使用教程
- 神经元人体分布大图,人体的神经元图片
- 一文盘点目前免费的云服务器
- python应用学习(三)——pyttsx3用四行代码让python说话!
- 【组图】韩国美女明星蔡研---精彩写真
- Laplacian eigenmap 拉普拉斯特征映射
- 年薪30万+的HR这样做数据分析!(附关键指标免费模版)
- 用C语言写一个停车场管理系统代码
- @Valid对象嵌套List对象校验无效的解决方案
- buck dcm占空比计算_如何计算BOOST转换器的占空比