87 lines
3.0 KiB
Markdown
87 lines
3.0 KiB
Markdown
# 12.6 后端编码规范
|
||
|
||
:::tip 概述
|
||
后端规范汇总:分层职责、命名、错误处理、事务纪律、注释风格。多数条目在前文有机制详解,本节为速查总表。
|
||
:::
|
||
|
||
## 分层与依赖
|
||
|
||
```text
|
||
□ controller 薄层:只透传,无业务/无 dao/无手写响应
|
||
□ service 接口手维护:方法签名变更同步接口文件;禁 gf gen service 整体运行
|
||
□ logic 差异进 spec 声明与钩子;装不下就手写(逃生舱)
|
||
□ dao.Ctx 唯一查询入口;自定义 dao 方法也必须 Ctx 起手
|
||
□ 依赖红线:task→logic 单向;middleware 经 wire 接线;migrate 不走 dao
|
||
□ base.go 只依赖 dao/utility/consts;导出 ≤15
|
||
```
|
||
|
||
## 命名
|
||
|
||
```text
|
||
□ 文件:表名去 goframe_ 前缀 snake_case(config_item.go)
|
||
□ 控制器:CXxx(CConfigItem);logic 实现:sXxx
|
||
□ spec 变量:xxxSpec;字典映射:xxxSerializeMaps
|
||
□ service:IXxx 接口 / Xxx() 取用 / RegisterXxx() 注册
|
||
□ 权限码:sys:{module小驼峰}:{action}
|
||
□ 缓存键:easygoadmin: 前缀(consts/cache_key.go 统一)
|
||
□ json:驼峰(登录/令牌四字段下划线例外)
|
||
```
|
||
|
||
## 请求与响应
|
||
|
||
```text
|
||
□ 每接口一 Req/Res 结构体;内嵌 gmeta.Meta 全标签
|
||
□ 校验用 v 标签(required#文案);复杂校验在钩子
|
||
□ 分页 PageData;新增 {id};空结果 struct{}
|
||
□ 出参字段 dc 注释 + 行注释(OpenAPI 文档质量)
|
||
```
|
||
|
||
## 错误与日志
|
||
|
||
```text
|
||
□ gerror 上抛(NewCodef 语义码+消息);不吞 err
|
||
□ 钩子错误记 stage 日志后原样上抛
|
||
□ fmt.Println 禁用——用 glog(带上下文)
|
||
□ 敏感字段(password/salt/token)不进日志
|
||
□ panic 只在编程错误(mustAs 失败等);运行期错误返回 error
|
||
```
|
||
|
||
## 事务与并发
|
||
|
||
```text
|
||
□ WithTrans 包裹多表写;错误自动回滚
|
||
□ 事务内禁 HTTP/文件 IO;bcrypt 事务外预计算
|
||
□ 共享 map 加锁;goroutine 有生命周期管理
|
||
□ 大数据量用 ChunkQuery 分批;循环内禁止查库(批查)
|
||
```
|
||
|
||
## 注释风格
|
||
|
||
```text
|
||
□ 按当前功能直述(禁比较/来源痕迹/历史考古)
|
||
□ 导出函数/类型有注释(godoc 风格,首句概括)
|
||
□ 关键设计决策注释"为什么"(而非复述代码)
|
||
□ 生成物注释保留工具标记(勿删头注释)
|
||
```
|
||
|
||
## 静态门禁
|
||
|
||
```sh
|
||
go build ./... # 编译
|
||
go vet ./... # vet
|
||
test -z "$(gofmt -l .)" # 格式(CI 同款)
|
||
go test ./... # sqlite + hooks MySQL 集成测试
|
||
```
|
||
|
||
## 反例速查
|
||
|
||
```text
|
||
❌ g.DB().Table("goframe_user").Where(...) 绕过 dao
|
||
❌ .Where("del_flag", 0) 手写 应由 Ctx 注入
|
||
❌ WithTrans 内 bcrypt 拉长锁
|
||
❌ for range ids { dao.Xxx.One } N+1
|
||
❌ err 被 _ 丢弃 吞错误
|
||
❌ 接口返回 map[string]any 拼装 应有结构体契约
|
||
❌ 在钩子里 if module == "user" 基座禁止按模块分支
|
||
```
|