5.9 KiB
5.9 KiB
description, globs, alwaysApply
| description | globs | alwaysApply |
|---|---|---|
| Go 后端项目 portal-mini-go 的核心开发规范,涵盖错误处理、目录结构、API 约定、Context、并发、测试与命名等需要人工/AI 遵守的约定。适用于本项目所有 .go 代码。 | **/*.go | true |
portal-mini-go 后端开发规范
你是一名高级 Go 后端工程师。在编写、修改或审查本项目(portal-mini-go)的 Go 代码时,必须遵循以下规范。机器可自动处理的(gofmt/goimports/go vet)交由 lint 工具,以下约定需主动遵守。
0. 项目定位
- portal-mini-go 是基于 Go 的中后台/门户类后端服务。
- 语言版本:Go 1.22+。module 名:
portal-mini-go。 - 未在本规则中明确约定的,遵循 Effective Go 与 Google Go Style Guide。
1. 推荐技术栈(默认;若本项目实际采用不同框架,修改本规则对应条目并保持一致)
- Web 框架:gin
- 参数校验:go-playground/validator/v10(
bindingtag) - 配置:viper + YAML,支持环境变量覆盖
- 日志:
log/slog(结构化;生产 JSON、本地 text) - 数据库:GORM(MySQL / PostgreSQL)
- 缓存:go-redis/redis
- 测试:
testing+testify;mock 用gomock或 testify mock - 错误包装:
fmt.Errorf("...: %w", err)
2. 目录结构(强制)
cmd/ # 各可执行程序入口(main 包)
internal/ # 私有业务代码,禁止被外部模块 import
handler/ # HTTP 接入层
service/ # 业务逻辑
repository/ # 数据访问(DB/Redis)
model/ # 领域模型/实体
pkg/ # 内部可复用工具(非对外公开)
pkg/ # 对外公开、可安全被外部引用的公共库
configs/ # 配置文件模板
scripts/ # 构建/部署脚本
- 业务代码放
internal/,对外公开库放pkg/。 - 依赖方向:
handler → service → repository → model,禁止反向依赖与循环依赖。 - 禁止在 handler 中直接写 SQL 或调用 DB,必须经 service / repository 层。
3. 错误处理(重点,必须)
- 永远不要忽略 error;
_ = f()必须加注释说明为何可忽略,否则必须处理。 - 向上传播错误使用
fmt.Errorf("上下文: %w", err)保留错误链路。 - 本层能合理处理才处理,否则向上返回;最终在 handler 层统一转换为 HTTP 状态码/响应。
- 禁止用
panic控制业务流程;recover仅允许用于 goroutine 顶层与框架中间件。 - 业务错误用哨兵变量或实现
error接口的类型,并携带可被前端消费的错误码(如var ErrNotFound = errors.New("not found"))。
4. 命名与风格
- 遵循 Go 惯例:导出标识符用驼峰;缩略语全大写(
ID、URL、HTTP、API)。 - 文件名小写下划线:
user_handler.go。 - 方法接收者用类型缩写(
u *User),禁止this/self。 - 接口优先做小接口(单方法,常以
-er结尾,如Reader、Closer)。 - 错误变量用
Err前缀;包级常量用const块,避免裸魔法数字。
5. 日志
- 统一使用
log/slog,禁止fmt.Println/log.Print记录业务日志。 - 关键路径记录 trace_id(从 context 取)、处理耗时、参数摘要;禁止打印敏感信息与超大对象。
- 级别:debug(开发)、info(正常)、warn(可恢复异常)、error(需告警)。
- 记录错误时必须带原始 error:
slog.Any("err", err)。
6. Context 与超时
- 所有跨进程调用(HTTP / DB / Redis / RPC)必须把
context.Context作为第一个参数接收并向下透传。 - 不在 struct 字段中存储 context;用
context.WithTimeout/WithDeadline设置超时。 - 长生命周期场景禁止用
time.After(会泄漏),改用time.NewTimer并显式Stop。
7. 并发
- 共享状态必须用
sync.Mutex/atomic/ channel 同步,明确数据归属。 - 每个
go语句必须有明确的生命周期与退出条件;主 goroutine 退出前用sync.WaitGroup或errgroup等待。 - 禁止无限制启动 goroutine;批量任务用受限 worker / 带缓冲 channel。
- 一组相关 goroutine 优先用
golang.org/x/sync/errgroup管理错误与取消。
8. HTTP / API
- RESTful 风格;统一响应结构:
type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data interface{} `json:"data,omitempty"` } - 用统一中间件将 error 转换为响应,handler 内不直接散落
c.JSON(http.StatusXxx, ...)处理错误。 - 入参用 struct + validator 校验(
binding:"required"等),禁止信任未校验的客户端输入。 - 所有 DB 查询使用参数化(GORM 占位符 / 预编译),禁止字符串拼接 SQL,杜绝注入。
9. 测试
- 核心 service / repository 必须写表驱动测试。
- 断言用
testify/require(失败即停)或assert;测试文件_test.go与被测同包或_test包。 - 外部依赖(DB / Redis / 下游服务)用接口 + mock 隔离,不在单测中依赖真实中间件。
- 提交前保证
go test ./...通过;核心业务逻辑覆盖率目标 ≥ 60%。
10. 配置与密钥
- 密钥、连接串、token 绝不硬编码或提交仓库;从环境变量 / 密钥管理服务读取。
- 配置优先级:默认值 < 配置文件 < 环境变量 < 命令行参数。
- 本地
.env必须加入.gitignore。
11. 提交与协作
- 提交信息遵循 Conventional Commits(
feat/fix/refactor/chore/docs/test)。 - 每次变更须通过
go vet、golangci-lint run、go test ./...后再提交。 - 不向主干(如
main)直接 push;重大改动走 PR / 评审。
当本规则与具体实现的第三方库文档冲突时,以库文档为准;若确定采用不同于"推荐技术栈"的框架,请同步修改本规则第 1 条,保持规则与代码一致。