# go-web-gin 一个基于 [Gin](https://github.com/gin-gonic/gin) 的 Go Web 应用脚手架,提供开箱即用的基础设施组件。 ## 特性 - 🚀 **快速启动** - 简洁的 API 设计,快速搭建 Web 服务 - 🔧 **配置管理** - 支持 YAML 配置文件和环境变量覆盖 - 📝 **结构化日志** - 基于 [Zap](https://github.com/uber-go/zap) 的高性能日志 - 🗄️ **数据库支持** - MySQL (GORM) 和 Redis 单例连接 - 🌍 **多环境** - 支持 Local、Development、Production 环境 - 🧩 **单例模式** - 组件单例管理,避免重复初始化 ## 安装 ```bash go get git.hujye.com/infrastructure/go-web-gin ``` ## 快速开始 ### 1. 创建配置文件 在项目根目录创建 `config/config.yml`: ```yaml server: host: 0.0.0.0 port: 8080 mode: debug # debug, release, test app: name: my-app environment: local log_level: info log: output_to_file: true filename: logs/app.log max_size: 100 max_backups: 3 max_age: 28 compress: true mysql: host: 127.0.0.1 port: 3306 user: root password: "" db_name: test charset: utf8mb4 parse_time: true max_idle_conns: 10 max_open_conns: 100 conn_max_lifetime: 3600 redis: addr: 127.0.0.1:6379 password: "" db: 0 pool_size: 10 min_idle_conns: 5 max_retries: 3 dial_timeout: 5 read_timeout: 3 write_timeout: 3 ``` ### 2. 编写主程序 ```go package main import ( "context" go_web_gin "git.hujye.com/infrastructure/go-web-gin" "github.com/gin-gonic/gin" ) func main() { // 创建应用实例 app := go_web_gin.New() // 初始化数据库(可选) app.InitMySQL() app.InitRedis() // 注册全局中间件 app.UseMiddleware(gin.Recovery()) // 注册路由 app.RegisterRoutes(func(e *gin.Engine) { e.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{"message": "pong"}) }) e.GET("/users/:id", func(c *gin.Context) { id := c.Param("id") // 使用日志 app.Logger().Info(c.Request.Context(), "get user", "id", id) c.JSON(200, gin.H{"user_id": id}) }) // 使用数据库 e.GET("/db-test", func(c *gin.Context) { db := app.DB() if db != nil { // 执行数据库操作 c.JSON(200, gin.H{"db": "connected"}) } else { c.JSON(500, gin.H{"error": "db not initialized"}) } }) // 使用 Redis e.GET("/redis-test", func(c *gin.Context) { rdb := app.Redis() if rdb != nil { rdb.Set(c.Request.Context(), "test", "value", 0) c.JSON(200, gin.H{"redis": "connected"}) } else { c.JSON(500, gin.H{"error": "redis not initialized"}) } }) }) // 启动服务 // 非生产环境可传入自定义地址,生产环境使用配置文件地址 app.Run() } ``` ## API 文档 ### App 结构 ```go type App struct { engine *gin.Engine db *gorm.DB rdb *redis.Client logger *logger.Logger } ``` ### 方法列表 | 方法 | 说明 | 返回值 | |------|------|--------| | `New()` | 创建新的 App 实例 | `*App` | | `UseMiddleware(...)` | 注册全局中间件 | - | | `RegisterRoutes(func)` | 注册路由 | - | | `InitMySQL()` | 初始化 MySQL 连接 | `*gorm.DB` | | `InitRedis()` | 初始化 Redis 连接 | `*redis.Client` | | `DB()` | 获取数据库实例 | `*gorm.DB` | | `Redis()` | 获取 Redis 实例 | `*redis.Client` | | `Logger()` | 获取日志实例 | `*logger.Logger` | | `Run(addr ...string)` | 启动服务 | `error` | ### Run 方法行为 - **非生产环境**:优先使用传入的地址,否则使用配置文件地址 - **生产环境**:始终使用配置文件地址 ```go // 使用配置文件地址 app.Run() // 非生产环境使用 :3000,生产环境仍用配置文件地址 app.Run(":3000") ``` ## 环境变量 | 变量 | 说明 | 默认值 | |------|------|--------| | `RUN_ENV` | 运行环境 (`LOCAL`, `DEVELOPMENT`, `PRODUCTION`) | `LOCAL` | | `CFG_PATH` | 配置文件路径 | `config/config.yml` | ## 日志使用 ```go // 基本用法 app.Logger().Info(ctx, "message") app.Logger().Error(ctx, "error message") app.Logger().Warn(ctx, "warning message") app.Logger().Debug(ctx, "debug message") // 带键值对 app.Logger().Info(ctx, "user logged in", "user_id", "123", "ip", "192.168.1.1") ``` 日志格式会根据环境自动切换: - **Local**: Console 格式,便于阅读 - **Development/Production**: JSON 格式,便于日志收集 ## 上下文用户信息 使用 `web` 包在上下文中传递用户信息: ```go import "git.hujye.com/infrastructure/go-web-gin/web" // 设置用户信息 ctx = web.SetUserID(ctx, "user-123") ctx = web.SetUserName(ctx, "john") ctx = web.SetTrace(ctx, "trace-456") ctx = web.SetFromIP(ctx, "192.168.1.1") // 获取用户信息 userID := web.GetUserID(ctx) userName := web.GetUserName(ctx) // 或一次性构建 userInfo := web.NewUserInfo(). WithUserID("user-123"). WithUserName("john"). WithTrace("trace-456"). WithFromIP("192.168.1.1") ctx = web.ToContext(ctx, userInfo) ``` 日志会自动从上下文中提取用户信息并记录。 ## 使用 svr 包直接操作 Gin 如果需要直接使用 Gin 引擎单例: ```go import "git.hujye.com/infrastructure/go-web-gin/svr" // 获取引擎 engine := svr.GetEngine() // 快捷方法 svr.Use(middleware...) svr.GET("/ping", handler) svr.POST("/users", handler) svr.PUT("/users/:id", handler) svr.DELETE("/users/:id", handler) // 路由组 api := svr.Group("/api/v1") api.GET("/users", handler) // 启动服务 svr.Run(":8080") ``` ## 配置读取 ```go import "git.hujye.com/infrastructure/go-web-gin/config" // 获取完整配置 cfg := config.Get() // 访问配置项 addr := cfg.GetAddr() // host:port isDebug := cfg.IsDebug() // 是否 debug 模式 isRelease := cfg.IsRelease() // 是否 release 模式 // 动态读取配置(支持嵌套键) dbHost := config.GetString("mysql.host") dbPort := config.GetInt("mysql.port") ``` ## 项目结构 ``` go-web-gin/ ├── app.go # 应用核心 ├── app_test.go # 测试套件 ├── config/ │ └── config.go # 配置管理 ├── database/ │ ├── mysql.go # MySQL 单例 │ └── redis.go # Redis 单例 ├── env/ │ └── env.go # 环境变量 ├── logger/ │ ├── logger.go # 日志核心 │ ├── encoder.go # 编码器 │ └── struct.go # 结构定义 ├── server/ │ └── server.go # 服务器封装 ├── svr/ │ └── server.go # Gin 单例 └── web/ └── user.go # 上下文用户信息 ``` ## 运行测试 ```bash # 运行所有测试 go test -v ./... # 运行特定测试套件 go test -v ./... -run TestAppRunSuite ``` ## 依赖 - [gin-gonic/gin](https://github.com/gin-gonic/gin) - Web 框架 - [uber-go/zap](https://github.com/uber-go/zap) - 高性能日志 - [go-gorm/gorm](https://github.com/go-gorm/gorm) - ORM - [redis/go-redis](https://github.com/redis/go-redis) - Redis 客户端 - [spf13/viper](https://github.com/spf13/viper) - 配置管理 - [stretchr/testify](https://github.com/stretchr/testify) - 测试框架 ## License MIT License ## Author **hujye** - Email: hujie@hujye.com