temp commit
commit
24c7ca651d
|
|
@ -0,0 +1,124 @@
|
||||||
|
# Go通用Web项目编码风格/规范
|
||||||
|
|
||||||
|
## 使用的包
|
||||||
|
|
||||||
|
* HTTP使用gin框架
|
||||||
|
* ORM使用GORM框架
|
||||||
|
* Postgre的驱动使用`gorm.io/driver/postgres`
|
||||||
|
* Mysql驱动使用`gorm.io/driver/mysql`
|
||||||
|
|
||||||
|
## 代码目录结构
|
||||||
|
|
||||||
|
```txt
|
||||||
|
magi-forge/
|
||||||
|
├── web/ # 前端项目
|
||||||
|
├── app/ # 应用层
|
||||||
|
│ └── model/ # 数据模型
|
||||||
|
│ └── service/ # 业务逻辑层
|
||||||
|
│ └── api/ # API 层 (Controller层)
|
||||||
|
│ └── common/ # 通用代码, 包括错误定义, 响应格式等
|
||||||
|
├── cmd/ # 命令行入口
|
||||||
|
│ └── apiserver/ # API 服务器
|
||||||
|
│ └── xxxx/ # 其他CLI或服务
|
||||||
|
└── pkg/ # 可复用包
|
||||||
|
├── autoload/ # 自动加载器, 用于统一按照执行顺序加载所有全局单例
|
||||||
|
├── config/ # 配置管理, 用于管理所有配置项
|
||||||
|
├── dao/ # 数据访问层, 用于访问外部服务, 包括数据库, Redis, 外部HTTP Client等
|
||||||
|
└── logger/ # 用于统一日志输出
|
||||||
|
```
|
||||||
|
|
||||||
|
## 全局单例说明
|
||||||
|
|
||||||
|
默认需要全局单例的包有:
|
||||||
|
- config
|
||||||
|
- dao
|
||||||
|
|
||||||
|
* 全局单例包必须实现Get()方法, 用于获取单例实例
|
||||||
|
* 全局单例包必须实现Autoload()方法, 用于给autoload包调用, 用于创建全局单例实例
|
||||||
|
* 如果用户指定了其他全局单例, 则需要参照以上说明实现
|
||||||
|
|
||||||
|
## autoload包说明
|
||||||
|
|
||||||
|
autoload包必须实现autoload.go文件的Autoload()方法,且不传递和返回任何参数, 出错就直接panic
|
||||||
|
|
||||||
|
Autoload方法有执行顺序, 其中config包必须第一个调用, 其他全局单例包的Autoload方法根据实际情况调用
|
||||||
|
|
||||||
|
## model层(GORM模型声明规范)
|
||||||
|
|
||||||
|
**需要时必须显示声明的注解包括**
|
||||||
|
|
||||||
|
* column
|
||||||
|
* primaryKey
|
||||||
|
* autoIncrement
|
||||||
|
* type
|
||||||
|
* json
|
||||||
|
* 指针类型需要定义json omitempty标签, 避免在json序列化时出现空值
|
||||||
|
|
||||||
|
**必须实现的方法包括**
|
||||||
|
|
||||||
|
* TableName() string
|
||||||
|
|
||||||
|
**关联模型要求**
|
||||||
|
|
||||||
|
* 关联的对象均使用指针, 避免没有Preload时关联对象是默认值对象
|
||||||
|
* Migrate时不允许创建实际的外键, 也就是Dao需要配置`DisableForeignKeyConstraintWhenMigrating: true,`
|
||||||
|
|
||||||
|
### PostgreSQL 模型声明规范
|
||||||
|
|
||||||
|
* 数组采用github.com/lib/pq中的各种Array类型
|
||||||
|
* jsonb采用datatypes.JSONType[Go Struct]
|
||||||
|
|
||||||
|
## API(Controller)层编码规范
|
||||||
|
|
||||||
|
* 每一组业务的Controller都用一个struct承载, 但是struct里不要放入注入任何对象
|
||||||
|
* 业务需要的Service在每次实际调用时直接NewService
|
||||||
|
* Controller不要编写复杂业务逻辑, 而是组合1个或多个Service
|
||||||
|
* 路由定义在`app/api/routes_define.go`文件的`RegisterRoutes`方法中
|
||||||
|
* API不需要版本前缀
|
||||||
|
* 路由必须有/api前缀
|
||||||
|
|
||||||
|
### 标准API响应
|
||||||
|
|
||||||
|
* 无特殊要求时所有API都返回JSON格式, 包含code, message, data三个字段
|
||||||
|
* code为int类型, 0表示成功, 其他值表示失败
|
||||||
|
* message为string类型, 用于描述失败原因
|
||||||
|
* data为任意类型, 用于返回业务数据
|
||||||
|
* Code需要在common包中的`code.go`中定义
|
||||||
|
|
||||||
|
**示例**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"message": "ok",
|
||||||
|
"data": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
可以直接使用common包中的`response.go`定义的方法
|
||||||
|
|
||||||
|
## Service层编码规范
|
||||||
|
|
||||||
|
* 每一组业务的Service都用一个struct承载, 但是struct里不要放入注入任何对象
|
||||||
|
* Service每个需要数据库操作的方法, 第一个参数都需要传递一个tx *gorm.DB, 用于数据库事务
|
||||||
|
* 每个Service需要实现一个NewService方法, 但是没有要求时不需要传递任何函数, 直接返回Service{}即可
|
||||||
|
|
||||||
|
## 前端规范
|
||||||
|
|
||||||
|
* 后端暴露/ui/*路径, 用于前端访问
|
||||||
|
* 后端的/直接跳转/ui/路径
|
||||||
|
* 使用Next.js + Ant Design6作为后台框架
|
||||||
|
* 后台如果有代码编写组件使用Monaco Editor
|
||||||
|
* 默认不需要开发任何认证、鉴权部分
|
||||||
|
* 后台管理使用左右栏布局, 左侧为菜单, 右侧为内容区域
|
||||||
|
* API定义读取后端代码
|
||||||
|
* 尽量借鉴后端model的注释来理解需求
|
||||||
|
* 访问后端接口使用相对路由
|
||||||
|
|
||||||
|
## 其他编码规范
|
||||||
|
|
||||||
|
* 默认代码只分api -> service -> model三层, 没有特殊要求不要引入repo层等
|
||||||
|
* 没有额外要求时不编写单元测试
|
||||||
|
* 不要过度设计, 不复杂的代码不要刻意拆分额外的函数
|
||||||
|
* 项目的业务代码主要使用全局单例
|
||||||
|
* 使用`any`而不是`interface{}`
|
||||||
Loading…
Reference in New Issue