在 Go 语言 Gin 框架中,合理的项目结构对可维护性和扩展性至关重要。以下是经过实践验证的推荐项目结构及说明:
推荐项目结构
my-gin-project/
├── cmd/ # 项目入口 (main.go)
│ └── main.go
├── internal/ # 私有代码 (禁止外部导入)
│ ├── app/ # 核心应用逻辑
│ │ ├── controllers/ # 控制器层 (HTTP 请求处理)
│ │ ├── models/ # 数据模型/数据库结构
│ │ ├── services/ # 业务逻辑层
│ │ └── repositories/ # 数据访问层 (DAO)
│ ├── config/ # 配置文件加载
│ │ └── config.go
│ ├── routes/ # 路由定义
│ │ └── router.go
│ └── middleware/ # 自定义中间件
├── pkg/ # 公共库代码 (允许外部导入)
├── api/ # OpenAPI/Swagger 文档
├── scripts/ # 脚本文件 (迁移/部署)
├── tests/ # 集成测试/端到端测试
├── web/ # 前端静态文件 (可选)
├── .env # 环境变量配置
├── go.mod # Go 模块管理
├── Dockerfile # 容器化配置
└── README.md # 项目文档
核心目录说明
cmd/main.go
- 单一入口原则,仅初始化配置和启动服务
- 示例代码:
func main() {
cfg := config.LoadConfig()
router := routes.SetupRouter(cfg)
router.Run(":" + cfg.ServerPort)
}
internal/app/
controllers: 处理 HTTP 请求,调用 Service 层
type UserController struct {
Service services.UserService
}
func (c *UserController) GetUser(ctx *gin.Context) {
// 参数校验 -> 调用 Service -> 返回响应
}
services: 业务逻辑实现,调用 Repository
repositories: 数据库操作层,使用 GORM/SQLX 等
models: 数据结构定义,添加 JSON/DB 标签
internal/config/
- 使用 Viper 或环境变量加载配置
- 示例配置结构:
type Config struct {
DBHost string `mapstructure:"DB_HOST"`
DBPort int `mapstructure:"DB_PORT"`
ServerPort string `mapstructure:"SERVER_PORT"`
}
internal/routes/
路由分组和中间件注入
示例路由配置:
func SetupRouter(cfg *config.Config) *gin.Engine {
r := gin.Default()
r.Use(middleware.Logger())
api := r.Group("/api/v1")
{
userCtrl := controllers.NewUserController()
api.GET("/users", userCtrl.GetUsers)
api.POST("/users", userCtrl.CreateUser)
}
return r
}
internal/middleware/
- 自定义中间件 (JWT 验证、限流等)
- 示例中间件:
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
// 验证逻辑
c.Next()
}
}
关键实践建议
依赖注入
type UserService interface {
GetUser(id uint) (*models.User, error)
}
type userServiceImpl struct {
repo repositories.UserRepository
}
func NewUserService(repo repositories.UserRepository) UserService {
return &userServiceImpl{repo: repo}
}
统一响应格式
func SuccessResponse(ctx *gin.Context, data interface{}) {
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": data,
})
}
func ErrorResponse(ctx *gin.Context, code int, message string) {
ctx.JSON(code, gin.H{
"code": code,
"message": message,
"data": nil,
})
}
集成常用组件
- 数据库: GORM + MySQL/PostgreSQL
- 缓存: Redis 客户端
- 文档: Swagger 自动生成
- 日志: Zap 或 Logrus
- 配置管理: Viper
- 测试: Testify + GoMock
扩展建议
- 增加
Makefile
管理常用命令 - 使用
wire
实现编译时依赖注入 - 添加
migrations/
目录管理数据库变更 - 集成 Prometheus 监控
- 使用
air
实现热重载开发
这种结构清晰划分层级,符合 Go 的简洁哲学,同时具备良好的扩展性,适合从中小型项目到大型微服务的演进。