竹简文档
上下文

工具函数

xCtxUtil 包提供便捷的上下文操作函数,已解耦 Gin 框架

工具函数

xCtxUtil 包提供便捷的上下文操作函数,使用标准 context.Context 实现框架解耦

import xCtxUtil "github.com/bamboo-services/bamboo-base-go/common/utility/context"

设计理念

新版 xCtxUtil 采用双版本 API 设计:

版本前缀行为适用场景
Panic 版本Must*失败时 panic确定资源已注入的场景
错误返回版本Get*返回 *xError.Error需要优雅处理错误的场景

通用函数

IsDebugMode

判断当前是否处于调试模式。

common.go
func IsDebugMode() bool

实现:

common.go
func IsDebugMode() bool {
    return xEnv.GetEnvBool(xEnv.Debug, false)
}

示例:

if xCtxUtil.IsDebugMode() {
    // 调试模式下的特殊处理
    log.Debug(ctx, "调试信息")
}

CalcOverheadTime

计算当前请求的耗时(微秒级)。

common.go
func CalcOverheadTime(ctx context.Context) int64

说明:

  • 仅在调试模式下计算耗时
  • 非调试模式始终返回 0
  • 单位为微秒(microseconds)

示例:

overhead := xCtxUtil.CalcOverheadTime(c.Request.Context())
// overhead = 1234 (微秒)

GetRequestKey

获取请求唯一标识。

common.go
func GetRequestKey(ctx context.Context) string

示例:

requestID := xCtxUtil.GetRequestKey(c.Request.Context())
// requestID = "550e8400-e29b-41d4-a716-446655440000"

GetErrorMessage

获取上下文中的错误消息。

common.go
func GetErrorMessage(ctx context.Context) string

通用组件获取

当需要读取自定义注入的组件时,可使用泛型的 MustGet / Get

import xCtx "github.com/bamboo-services/bamboo-base-go/defined/context"

MustGet

通用组件获取(Panic 版本)。

custom.go
func MustGet[T any](ctx context.Context, key xCtx.ContextKey) T

读取优先级:

  1. RegNodeKey 聚合的节点列表
  2. ctx.Value(key)

说明:

  • 若传入 *gin.Context 会自动转换为 c.Request.Context()
  • 未找到组件时会触发 panic

示例:

// 直接从 Gin 上下文获取
cache := xCtxUtil.MustGet[*xCache.Cache](c, xCtx.CacheKey)

// 或者先获取标准 context
ctx := c.Request.Context()
cache := xCtxUtil.MustGet[*xCache.Cache](ctx, xCtx.CacheKey)

Get

通用组件获取(错误返回版本)。

custom.go
func Get[T any](ctx context.Context, key xCtx.ContextKey) (T, *xError.Error)

示例:

cache, err := xCtxUtil.Get[*xCache.Cache](ctx, xCtx.CacheKey)
if err != nil {
    return nil, err
}

MustGetDB

从上下文获取 GORM 数据库连接(Panic 版本)。

database.go
func MustGetDB(ctx context.Context) *gorm.DB

注意:

  • 如果上下文中未找到数据库连接,会触发 panic
  • 返回的连接已自动绑定当前上下文(WithContext

示例:

func GetUser(ctx *gin.Context, id string) (*entity.User, error) {
    db := xCtxUtil.MustGetDB(ctx.Request.Context())

    var user entity.User
    if err := db.Where("id = ?", id).First(&user).Error; err != nil {
        return nil, err
    }
    return &user, nil
}

GetDB

从上下文获取 GORM 数据库连接(错误返回版本)。

database.go
func GetDB(ctx context.Context) (*gorm.DB, *xError.Error)

示例:

func GetUser(ctx *gin.Context, id string) (*entity.User, *xError.Error) {
    db, err := xCtxUtil.GetDB(ctx.Request.Context())
    if err != nil {
        return nil, err
    }

    var user entity.User
    if dbErr := db.Where("id = ?", id).First(&user).Error; dbErr != nil {
        return nil, xError.NewInternalServerError(ctx.Request.Context(), "查询失败", dbErr)
    }
    return &user, nil
}

Redis 函数

MustGetRDB

从上下文获取 Redis 客户端(Panic 版本)。

nosql.go
func MustGetRDB(ctx context.Context) *redis.Client

注意:

  • 如果上下文中未找到 Redis 客户端,会触发 panic

示例:

func GetCache(ctx *gin.Context, key string) (string, error) {
    rdb := xCtxUtil.MustGetRDB(ctx.Request.Context())

    return rdb.Get(ctx, key).Result()
}

GetRDB

从上下文获取 Redis 客户端(错误返回版本)。

nosql.go
func GetRDB(ctx context.Context) (*redis.Client, *xError.Error)

示例:

func GetCache(ctx *gin.Context, key string) (string, *xError.Error) {
    rdb, err := xCtxUtil.GetRDB(ctx.Request.Context())
    if err != nil {
        return "", err
    }

    val, redisErr := rdb.Get(ctx, key).Result()
    if redisErr != nil {
        return "", xError.NewError(ctx.Request.Context(), xError.CacheError, "缓存读取失败", false, redisErr)
    }
    return val, nil
}

雪花算法函数

GetSnowflakeNode

从上下文获取雪花算法节点。

snowflake.go
func GetSnowflakeNode(ctx context.Context) *xSnowflake.Node

说明:

  • 如果上下文中不存在节点,会回退到默认节点
  • 确保即使在非 HTTP 请求上下文中也能正常生成 ID

示例:

node := xCtxUtil.GetSnowflakeNode(ctx.Request.Context())
id := node.MustGenerate()

MustGenerateSnowflakeID

生成普通雪花 ID(Panic 版本)。

snowflake.go
func MustGenerateSnowflakeID(ctx context.Context) xSnowflake.SnowflakeID

示例:

id := xCtxUtil.MustGenerateSnowflakeID(ctx.Request.Context())
// id = 1234567890123456789

GenerateSnowflakeID

生成普通雪花 ID(错误返回版本)。

snowflake.go
func GenerateSnowflakeID(ctx context.Context) (xSnowflake.SnowflakeID, error)

MustGenerateGeneSnowflakeID

生成带业务基因的雪花 ID(Panic 版本)。

snowflake.go
func MustGenerateGeneSnowflakeID(ctx context.Context, gene xSnowflake.Gene) xSnowflake.SnowflakeID

示例:

// 生成用户 ID
userID := xCtxUtil.MustGenerateGeneSnowflakeID(ctx.Request.Context(), xSnowflake.GeneUser)

// 生成订单 ID
orderID := xCtxUtil.MustGenerateGeneSnowflakeID(ctx.Request.Context(), xSnowflake.GeneOrder)

GenerateGeneSnowflakeID

生成带业务基因的雪花 ID(错误返回版本)。

snowflake.go
func GenerateGeneSnowflakeID(ctx context.Context, gene xSnowflake.Gene) (xSnowflake.SnowflakeID, error)

函数一览

字段

类型

完整示例

service.go
package logic

import (
    "context"

    xError "github.com/bamboo-services/bamboo-base-go/common/error"
    xSnowflake "github.com/bamboo-services/bamboo-base-go/common/snowflake"
    xCtxUtil "github.com/bamboo-services/bamboo-base-go/common/utility/context"
    "github.com/gin-gonic/gin"
)

func (l *UserLogic) CreateUser(c *gin.Context, username string) (*entity.User, *xError.Error) {
    // 获取标准上下文
    ctx := c.Request.Context()

    // 获取数据库连接(错误返回版本)
    db, err := xCtxUtil.GetDB(ctx)
    if err != nil {
        return nil, err
    }

    // 生成用户 ID(Panic 版本,确定雪花节点已注入)
    userID := xCtxUtil.MustGenerateGeneSnowflakeID(ctx, xSnowflake.GeneUser)

    user := &entity.User{
        Username: username,
    }
    user.ID = userID

    if dbErr := db.Create(user).Error; dbErr != nil {
        return nil, xError.NewInternalServerError(ctx, "创建用户失败", dbErr)
    }

    // 缓存用户信息(Panic 版本)
    rdb := xCtxUtil.MustGetRDB(ctx)
    rdb.Set(ctx, "user:"+userID.String(), user, time.Hour)

    return user, nil
}

迁移指南

从旧版本迁移到新版本:

旧版本新版本
xCtxUtil.GetDB(c *gin.Context)xCtxUtil.MustGetDB(c.Request.Context())
xCtxUtil.GetRDB(c *gin.Context)xCtxUtil.MustGetRDB(c.Request.Context())
xCtxUtil.GetSnowflakeNode(c *gin.Context)xCtxUtil.GetSnowflakeNode(c.Request.Context())
xCtxUtil.GenerateSnowflakeID(c *gin.Context)xCtxUtil.MustGenerateSnowflakeID(c.Request.Context())
xCtxUtil.GenerateGeneSnowflakeID(c, gene)xCtxUtil.MustGenerateGeneSnowflakeID(c.Request.Context(), gene)

关键变化:

  1. 参数从 *gin.Context 改为 context.Context
  2. 在 Gin Handler 中使用 c.Request.Context() 获取上下文
  3. 新增 Get* 系列函数返回错误而非 panic

下一步

On this page