中小型项目应选 gin-mvc 或 gin-scaffold;gin-admin 适合需 rbac 的场景;gin-ddd 仅适用于已有 rocketmq 且计划微服务的大型项目,其余情况易因配置、依赖和启动顺序问题导致调试困难。

选 Gin 脚手架前先看清楚项目规模
中小型项目直接用 gin-mvc 脚手架就够了,别一上来就套 DDD。DDD 的 gin-ddd 项目目录深、依赖重(RocketMQ、双数据库、事件总线),开发启动慢、本地调试成本高。你团队只有 3–5 人、接口不到 50 个、没复杂领域规则,用 MVC 分层(controller / service / repository)完全够用,且 gin-mvc 和 gin-scaffold 都支持 YAML/TOML 多环境配置、统一响应封装、中间件热插拔。
- 接口少、迭代快 → 选
gin-scaffold:结构扁平,dao直接暴露 SQL 封装,适合快速 CRUD - 要 RBAC、权限细粒度控制 → 选
gin-admin:内置Casbin+Wire DI+Swag文档生成,但需手动跑wire gen - 已有 RocketMQ 基础设施、未来要拆微服务 → 才考虑
gin-ddd,否则光配rocketmq-client-gov5.3+ 就容易卡在go mod tidy报错
初始化时最容易卡在 go mod 和配置加载顺序
go mod 必须开启,且脚手架的 main.go 启动逻辑对配置加载时机很敏感。比如 gin-scaffold 要求启动时传入配置路径:go run main.go conf/dev.yaml;而 gin-admin 默认读 configs/dev/server.toml,路径写错直接 panic 报 open configs/dev/server.toml: no such file or directory。
- 所有脚手架都依赖
go.mod中的replace或require指向本地 fork 分支,别直接go get官方库 -
config初始化必须在logger和db之前,否则日志打不出、数据库连不上 ——gin-ddd/cmd/server/main.go里是按config → logger → db → mq顺序调用的 - YAML 配置里字段名大小写敏感,
mysql.host写成mysql.Host会导致连接池初始化失败,错误日志只显示failed to connect: dial tcp: lookup,不提示具体字段
路由和中间件别堆在 main.go 里
几乎所有脚手架都提供 router 目录或 router.go 文件,但新手常把全部路由注册、中间件绑定写进一个函数里,导致后期无法按业务模块隔离。正确做法是按功能分组注册,比如用户相关路由走 userRouter,订单走 orderRouter,每个 router 文件里用 r.Group("/api/v1/users") 显式声明前缀。
-
gin-admin的router/router.go用RegisterRoutes函数注入各模块路由,避免全局变量污染 - 中间件如
token_auth或panic恢复,应通过r.Use()绑定到 group,而不是全局限流 —— 否则健康检查接口/health也会被鉴权拦截 - Swagger 注解(
// @Summary)必须写在 handler 函数上方,且 handler 函数签名得是func(*gin.Context),写成闭包或方法绑定会丢失文档生成
DAO 层小心 GORM 自动迁移和表名映射
多数脚手架用 GORM,但默认开启 AutoMigrate 很危险。上线后执行 AutoMigrate 可能删字段、改类型,尤其当表里已有数据时。另外 GORM 的表名自动复数转换(User → users)和脚手架里定义的 TableName() 方法冲突,导致查不到数据却无报错。
-
gin-admin的model层显式定义TableName() string,返回小写单数名("user"),避免复数问题 -
gin-scaffold的dao/demo.go示例里直接写原生 SQL,绕过 GORM 映射,适合字段频繁变动的场景 - 生产环境务必关闭
AutoMigrate,用migrate工具或 SQL 脚本做变更,脚手架里的db.Init()函数里要注释掉db.AutoMigrate(&User{})
真正麻烦的是跨数据库事务 —— 脚手架里所谓“双数据库支持”只是配置分离,没提供分布式事务能力。订单写 PostgreSQL、用户写 MySQL,一旦失败没法回滚,得靠最终一致性补偿,这点文档里基本都不提。











