mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 05:56:38 +08:00
3.9 KiB
3.9 KiB
OpenFlare 特定项目开发准则 (Project Guidelines)
本文档定义了针对 OpenFlare 项目特定的后端开发约束、架构设计模式、GORM 数据库交互规范以及关键的 JSON 序列化避坑指南。所有参与项目后端开发的代码必须严格遵守。
1. 统一接口输入与响应处理(Controller 约束)
为了保证 API 的一致性,并消除控制器层中大量的样板代码,所有 Gin Controller 必须遵守以下规范:
1.1 参数解析与绑定
- URL ID 参数解析:必须调用统一的
parseIDParam(c)辅助函数。严禁手写strconv.ParseUint(c.Param("id"), ...)。 - JSON 请求体绑定:必须调用统一的
bindJSON(c, &input)辅助函数。严禁手动调用c.ShouldBindJSON或json.NewDecoder并重复编写错误返回逻辑。
1.2 标准 API 响应
- 所有控制器方法的返回必须统一使用
respondSuccess、respondFailure、respondBadRequest等标准方法。 - 严禁手写
c.JSON(http.StatusOK, gin.H{...}),以确保全局 API 响应字段结构(success/message/data)的百分之百一致。
Important
接口的入参解析与响应统一规范定义在 openflare_server/controller/response.go 中。
2. 纯净工具类与数据库逻辑完全隔离(Utils 约束)
为了确保代码的可测试性、高内聚和低耦合,utils/ 目录下的工具包必须保持纯净性:
2.1 无副作用与解耦原则
- 所有底层客户端与外部服务对接包(如
utils/acme证书操作、邮件发送、DNS 供应商对接等)必须完全剥离数据库或 GORM 依赖。 - 工具包中严禁导入
openflare/model包或直接访问数据库连接。它们应当只接受基础数据类型(如string、[]byte等)或本地无依赖结构体作为输入,并返回纯粹的计算或请求结果。
2.2 业务服务层(Service)职责
- 业务服务层
service/负责数据库实体的加载、组装、事务持久化,并将底层的具体网络或加密操作委托给utils/工具包。 - 这样不仅保证了底层工具类的百分之百可单元测试性,也维护了清晰的系统分层。
3. Go 泛型切片去重与 JSON 序列化陷阱(Slice 约束)
在进行切片操作和去重时,必须使用泛型辅助函数,并注意 Go Slice 的空/零值在 JSON 序列化中的表现。
3.1 避免重复编写 map-seen 逻辑
- 禁止在
service/或model/中手写临时的 map-seen 去重样板代码。 - 必须统一调用基于 Go 泛型实现的 openflare_server/utils/slice.go 中的
utils.Unique()辅助函数。
3.2 关键的 JSON 序列化规则(Nil vs. Empty Slice)
在 Go 中,未初始化的 nil 切片和已初始化的空切片 []T{} 在内存中不同,它们在序列化为 JSON 时也有着决定性的区别:
nil切片:序列化为 JSONnull。- 空切片 (
make([]T, 0)):序列化为 JSON[]。
Caution
开发避坑准则:
- GORM 数据库的很多 JSON/Array 字段(例如
domain_cert_ids、upstreams等)或配置版本变更检测机制(如checksum计算和diff检测),要求空数组在 JSON 中必须表示为[]而非null,否则会触发重复发布或解析失败的 bug。utils.Unique必须具备 Nil-Preservation(空值保留) 特性:
- 如果传入的 Slice 是
nil,它必须返回nil,以支持omitempty或在需要表示“缺失”的场景中输出null。- 如果传入的 Slice 不是
nil(即使长度为 0 或去重后长度为 0),它必须返回非 nil 的空切片make([]T, 0),以确保序列化为[]。- 所有类似的切片加工辅助函数都必须遵循此行为。