上下文
工具函数
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
判断当前是否处于调试模式。
func IsDebugMode() bool实现:
func IsDebugMode() bool {
return xEnv.GetEnvBool(xEnv.Debug, false)
}示例:
if xCtxUtil.IsDebugMode() {
// 调试模式下的特殊处理
log.Debug(ctx, "调试信息")
}CalcOverheadTime
计算当前请求的耗时(微秒级)。
func CalcOverheadTime(ctx context.Context) int64说明:
- 仅在调试模式下计算耗时
- 非调试模式始终返回 0
- 单位为微秒(microseconds)
示例:
overhead := xCtxUtil.CalcOverheadTime(c.Request.Context())
// overhead = 1234 (微秒)GetRequestKey
获取请求唯一标识。
func GetRequestKey(ctx context.Context) string示例:
requestID := xCtxUtil.GetRequestKey(c.Request.Context())
// requestID = "550e8400-e29b-41d4-a716-446655440000"GetErrorMessage
获取上下文中的错误消息。
func GetErrorMessage(ctx context.Context) string通用组件获取
当需要读取自定义注入的组件时,可使用泛型的 MustGet / Get:
import xCtx "github.com/bamboo-services/bamboo-base-go/defined/context"MustGet
通用组件获取(Panic 版本)。
func MustGet[T any](ctx context.Context, key xCtx.ContextKey) T读取优先级:
RegNodeKey聚合的节点列表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
通用组件获取(错误返回版本)。
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 版本)。
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 数据库连接(错误返回版本)。
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 版本)。
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 客户端(错误返回版本)。
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
从上下文获取雪花算法节点。
func GetSnowflakeNode(ctx context.Context) *xSnowflake.Node说明:
- 如果上下文中不存在节点,会回退到默认节点
- 确保即使在非 HTTP 请求上下文中也能正常生成 ID
示例:
node := xCtxUtil.GetSnowflakeNode(ctx.Request.Context())
id := node.MustGenerate()MustGenerateSnowflakeID
生成普通雪花 ID(Panic 版本)。
func MustGenerateSnowflakeID(ctx context.Context) xSnowflake.SnowflakeID示例:
id := xCtxUtil.MustGenerateSnowflakeID(ctx.Request.Context())
// id = 1234567890123456789GenerateSnowflakeID
生成普通雪花 ID(错误返回版本)。
func GenerateSnowflakeID(ctx context.Context) (xSnowflake.SnowflakeID, error)MustGenerateGeneSnowflakeID
生成带业务基因的雪花 ID(Panic 版本)。
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(错误返回版本)。
func GenerateGeneSnowflakeID(ctx context.Context, gene xSnowflake.Gene) (xSnowflake.SnowflakeID, error)函数一览
字段
类型
完整示例
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) |
关键变化:
- 参数从
*gin.Context改为context.Context - 在 Gin Handler 中使用
c.Request.Context()获取上下文 - 新增
Get*系列函数返回错误而非 panic