竹简文档
初始化

引擎初始化

engineInit 创建并配置 Gin 引擎,注册内置中间件和验证器,并注入初始化上下文

引擎初始化

engineInit 方法创建并配置 Gin 引擎,注册内置中间件、自定义验证器,并将初始化上下文注入到每个 HTTP 请求。

engineInit

register_gin.go
// 私有方法,在 Register 流程中自动调用
func (r *Reg) engineInit()

实现细节

register_gin.go
func (r *Reg) engineInit() {
    log := xLog.WithName(xLog.NamedINIT)

    log.Debug(r.Init.Ctx, "初始化 GIN 引擎")
    if !xCtxUtil.IsDebugMode() {
        gin.SetMode(gin.ReleaseMode)
    }

    // 注册验证器和翻译器
    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
        xVaild.RegisterTranslator(v)
        xVaild.RegisterCustomValidators(v)
    }

    // 创建 Gin 引擎并注册中间件
    r.Serve = gin.New(func(engine *gin.Engine) {
        engine.Use(xHelper.RequestContext())
        engine.Use(xHelper.PanicRecovery())
        engine.Use(xHelper.HttpLogger())
        engine.Use(injectContext(r.Init.Ctx))  // 注入初始化上下文
    })
}

上下文注入

关键改进:将节点管理器的上下文注入到每个 HTTP 请求:

register_gin.go
// 注入初始化上下文到每个请求
func injectContext(ctx context.Context) func(c *gin.Context) {
    return func(c *gin.Context) {
        // 将初始化上下文合并到请求上下文
        c.Request = c.Request.WithContext(ctx)
        c.Next()
    }
}

这意味着:

  • 所有通过节点注入的资源(数据库、Redis 等)都可以通过 c.Request.Context() 获取
  • 业务代码使用标准 context.Context,实现框架解耦

内置中间件

中间件说明
xHelper.RequestContext()请求上下文处理,生成请求 ID 等
xHelper.PanicRecovery()Panic 恢复,防止单个请求崩溃影响整个服务
xHelper.HttpLogger()HTTP 请求日志记录
injectContext(ctx)注入初始化上下文到请求

运行模式

根据 DEBUG 环境变量自动切换 Gin 运行模式:

环境变量Gin 模式说明
DEBUG=trueDebug输出详细调试信息
DEBUG=false 或未设置Release生产模式,关闭调试输出

验证器

翻译器

注册中文翻译器,将验证错误信息翻译为中文:

type CreateUserReq struct {
    Name  string `json:"name" binding:"required"`
    Email string `json:"email" binding:"required,email"`
}

// 验证失败时返回中文错误信息
// "Name 为必填字段"
// "Email 必须是有效的邮箱地址"

自定义验证器

框架预置了常用的自定义验证器:

type CreateUserReq struct {
    Phone string `json:"phone" binding:"required,phone"`  // 手机号验证
    IDCard string `json:"id_card" binding:"required,idcard"` // 身份证验证
}

使用引擎

初始化完成后,通过 reg.Serve 访问 Gin 引擎:

reg := xReg.Register(context.Background(), nodeList)

// 注册路由
reg.Serve.GET("/api/users", userHandler.List)
reg.Serve.POST("/api/users", userHandler.Create)
reg.Serve.PUT("/api/users/:id", userHandler.Update)

// 路由分组
api := reg.Serve.Group("/api/v1")
{
    api.GET("/products", productHandler.List)
    api.POST("/orders", orderHandler.Create)
}

// 启动服务
reg.Serve.Run(":8080")

在 Handler 中获取资源

func MyHandler(c *gin.Context) {
    // 获取标准上下文(包含所有注入的资源)
    ctx := c.Request.Context()

    // 使用 xCtxUtil 获取资源
    db := xCtxUtil.MustGetDB(ctx)
    rdb := xCtxUtil.MustGetRDB(ctx)
    node := xCtxUtil.GetSnowflakeNode(ctx)
}

下一步

On this page