很多 Go 项目随着功能变多,会出现一个问题:HTTP 处理、业务逻辑和数据库操作全混在一起。
短期看开发快,长期看会越来越难改。
我更推荐一个非常朴素的分层:
- Handler:只做参数解析、调用 Usecase、返回响应
- Usecase:承载业务规则和事务边界
- Repository:封装持久化细节(MySQL、Redis 等)
为什么这个结构适合 Go
Go 本身语言特性简单,最怕的是“结构复杂化”。
这套分层没有引入重量级框架,也不会过度设计。它的价值在于明确职责边界,让我们能低成本重构。
一个常见的演进顺序
我一般按下面顺序推进:
- 先把 Handler 和 DB 操作拆开,抽出 Repository
- 当业务规则变多,再引入 Usecase 层
- 最后通过接口隔离依赖,方便测试替身注入
这个顺序比一开始就把架构铺满更稳。
实战中的两个关键点
第一,错误要在边界处翻译。
数据库错误不应该直接冒泡给 API 用户,而应该在 Usecase 或 Handler 层转成明确的业务错误码。
第二,避免在 Repository 里塞业务判断。
Repository 只回答“数据怎么读写”,不要回答“业务应不应该这么做”。
写在最后
好架构不是目录看起来高级,而是团队在三个月后还能快速定位问题、放心改代码。
对 Go 后端来说,先让边界清晰,再追求抽象优雅。