完工撒花🎉🎉🎉~
两个月了,一天 14-16 小时,单休;恭喜自己学会了 Golang 撒花🎉🎉🎉~
实战项目已达商业可用级别,而且完全免费开源,求 star:ai-go-admin(github | gitee),可视化CRUD真的非常强大,欢迎在线体验一下:demo.ai-go-hub.com/#/admin。
继实战项目完工后的特性总结之后,现在总结一下目录结构相关的经验。目录结构不管是对于 AI 项目,还是普通项目,只要这项目还需要维护,都非常重要。
目录结构在定之前怎么定都行,而一旦定了,它会反过来管着你,定的好也可以帮你管着 AI。
一个简单的例子,在 Go 里边,一旦建立了 common / utils 目录,就会极易出现依赖导入的问题,如果你再配合上低审查的 AI 代码,那它就是个全局依赖洼地,是个代码垃圾抽屉。
我从一开始就极其重视目录结构的搭建,项目的每一个目录创建,都经过深思熟虑。
期间我还翻烂了同类 top 项目的目录结构,说实话很多都很乱,我来简单举几个例子:
单复数目录名混用
首先 Go 社区给包命名的定义:包名描述的是"这个包是什么",而不是"这个包里装了什么",所以应该使用单数。
当然,就算包名有定义,也不能说明使用复数有任何问题,可是临近的包一会儿单一会儿复,可就有点让人摸不着头脑了,比如:configs、internal/handler、internal/models
乱放
是的,就像把 txt 放在 mp4 目录、把茶叶倒进咖啡,有的项目做到了一种:彻底的、不沾一点边的、纯粹的乱放。
比如 internal/model 目录,它在 Go 社区属于是已经有共识的标准目录,用来 存放数据模型定义,主要是和数据库、业务实体相关的结构体。
有的项目,里边放 初始化数据库连接、分页 Scopes 我都觉得擦了点边,请问你把 向 HTTP 响应体写入数据(也就是创建统一的失败、成功响应)放进去是要干啥呢?
没有 internal
Go 从 1.4 版本(2014年)就开始支持 internal 包机制,实现路径里包含 internal 的包,只能被同模块树内的代码导入 ,外部模块无法 import。
但是很多项目,至今没有使用 internal 目录,而是将模型、控制器等业务代码直接放在根目录。那么 Go Web 项目一定得用 internal 吗?我说的不算,这个问题如果你问 AI 的话,它会直接告诉你如果你做 个人极小玩具、Demo 可以不用,internal 实现了边界约束、方便未来拆模块、微服务等等;或许是这些项目的作者是从其他语言转过来的,也可能是为了保持1.4 前版本的兼容性吧😂。
算了,错误示例不再多说了,这里没有提任何项目名,也不是黑谁,就随便聊聊😂
核心结构选型背景
说了这么多,那么真正好的目录结构是什么样的呢?Go 社区有很多种做法:
第一种:一个业务或者能力相关的都放在一个目录内(ddd),比如:
bash
├── internal/
│ ├── user/
│ │ ├── handler
│ │ ├── service
│ │ ├── repository
│ │ └── model
│ └── order/
│ │ ├── handler
│ │ ├── service
│ │ ├── repository
│ │ └── model
这种方案不合适我们,后台项目主要服务于管理员,而且主打极简内核,主要架构是单体(而非上来就分布式和抽一大堆微服务);如果用 ddd 前期发展试错阶段业务激增,同级能力极速增多,找文件夹都得翻页。
第二种:以 app 作为顶层,然后再以业务进行划分,比如:
bash
├── internal/
│ ├── app/
│ │ └── admin
│ │ │ ├── user/
│ │ │ │ ├── handler
│ │ │ │ ├── service
│ │ │ │ ├── repository
│ │ │ │ ├── model
│ │ │ └── order/
│ │ │ │ │ ├── handler
│ │ │ │ │ ├── service
│ │ │ │ │ ├── repository
│ │ │ │ │ └── model
这种方案,由于 go 中多了一层 internal,显得目录层级很深,而控制器、模型等又是经常改动的文件,难得翻。
第三种:即现在的方案,internal 下平铺分层架构的目录,放弃 app 目录,比如:
bash
├── internal/
│ ├── handler/
│ │ ├── user/
│ │ │ ├── log.go
│ │ │ ├── rule.go
│ │ │ ├── ...
│ │ │ └── group.go
│ ├── model/
│ ├── repository/
│ └── service/
放弃 app 目录,直接就让 层级 - 2 (去掉 app/admin 这种),新的结构到了 handler、model 以内:你想分的粗一点,就是 common、user、admin,而想分的细一点,可以是 group、log、rule、config、article、fields 等。
目前这种目录结构用起来非常舒心,展开时没有多余的点击,扩展也方便自然。
以上就是服务端目录结构的总结了,感谢您阅读到这里,也欢迎使用我们精心制作的开源后台:github.com/ai-go-hub/a...