Golang中如何将Fiber上下文传递至GQLGen的GraphQL解析器上下文
解决Fiber上下文值传递到GQLGen解析器的方案
核心原理
GQLGen的HTTP处理器基于标准库net/http,Fiber通过adaptor.HTTPHandler转换时,会将Fiber上下文的UserContext()(标准context.Context实例)传递给GQLGen的请求上下文。因此我们只需要在Fiber中间件中修改UserContext,注入需要的值或整个Fiber上下文即可。
方案一:传递单个指定值(推荐,类型安全)
适合只需要传递特定值的场景,避免解析器依赖整个Fiber上下文。
定义类型安全的Context Key
用自定义类型作为Key,避免与其他库的Key冲突:package main import "context" type contextKey string const myTestValueKey contextKey = "MyTestValue"编写Fiber中间件注入值
从Fiber上下文中提取目标值,存入标准Context并设置回Fiber的UserContext:func injectTestValue(c *fiber.Ctx) error { // 从Fiber Locals获取预先设置的值 testVal := c.Locals("MyTestValue") // 创建新的标准Context,注入值 newCtx := context.WithValue(c.UserContext(), myTestValueKey, testVal) // 更新Fiber的UserContext,让后续GQLGen处理器能拿到 c.SetUserContext(newCtx) return c.Next() }挂载路由时添加中间件
在GQLGen路由组先应用中间件,再接入GQLGen处理器:// gqlHandler是GQLGen生成的标准http.Handler app.Group("/graph").Use(injectTestValue).All(fiber.Handler(adaptor.HTTPHandler(gqlHandler)))在GQLGen解析器中获取值
通过自定义Key从标准Context中提取值:func (r *queryResolver) YourQuery(ctx context.Context) (string, error) { // 类型断言要检查ok,避免panic val, ok := ctx.Value(myTestValueKey).(string) if !ok { return "", fmt.Errorf("failed to retrieve MyTestValue from context") } return val, nil }
方案二:传递整个Fiber上下文(灵活)
适合需要在解析器中访问Fiber上下文多个功能的场景:
定义Context Key
type fiberCtxKey struct{} const fiberCtxKeyVal fiberCtxKey = struct{}{}编写中间件注入Fiber上下文
func injectFiberCtx(c *fiber.Ctx) error { newCtx := context.WithValue(c.UserContext(), fiberCtxKeyVal, c) c.SetUserContext(newCtx) return c.Next() }挂载路由(同方案一)
app.Group("/graph").Use(injectFiberCtx).All(fiber.Handler(adaptor.HTTPHandler(gqlHandler)))解析器中获取Fiber上下文并取值
func (r *queryResolver) YourQuery(ctx context.Context) (string, error) { fiberCtx, ok := ctx.Value(fiberCtxKeyVal).(*fiber.Ctx) if !ok { return "", fmt.Errorf("failed to get Fiber context") } val, ok := fiberCtx.Locals("MyTestValue").(string) if !ok { return "", fmt.Errorf("MyTestValue not found or invalid type") } return val, nil }
常见问题排查
- 若之前中间件无效,大概率是没修改Fiber的
UserContext(),而是直接操作了GQLGen的Context,这会导致值无法传递。 - 务必使用自定义类型作为Context Key,不要用字符串,避免命名冲突。
- 类型断言必须检查
ok状态,防止因类型不匹配引发panic。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

