You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中如何将Fiber上下文传递至GQLGen的GraphQL解析器上下文

解决Fiber上下文值传递到GQLGen解析器的方案

核心原理

GQLGen的HTTP处理器基于标准库net/http,Fiber通过adaptor.HTTPHandler转换时,会将Fiber上下文的UserContext()(标准context.Context实例)传递给GQLGen的请求上下文。因此我们只需要在Fiber中间件中修改UserContext,注入需要的值或整个Fiber上下文即可。


方案一:传递单个指定值(推荐,类型安全)

适合只需要传递特定值的场景,避免解析器依赖整个Fiber上下文。

  1. 定义类型安全的Context Key
    用自定义类型作为Key,避免与其他库的Key冲突:

    package main
    
    import "context"
    
    type contextKey string
    
    const myTestValueKey contextKey = "MyTestValue"
    
  2. 编写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()
    }
    
  3. 挂载路由时添加中间件
    在GQLGen路由组先应用中间件,再接入GQLGen处理器:

    // gqlHandler是GQLGen生成的标准http.Handler
    app.Group("/graph").Use(injectTestValue).All(fiber.Handler(adaptor.HTTPHandler(gqlHandler)))
    
  4. 在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上下文多个功能的场景:

  1. 定义Context Key

    type fiberCtxKey struct{}
    
    const fiberCtxKeyVal fiberCtxKey = struct{}{}
    
  2. 编写中间件注入Fiber上下文

    func injectFiberCtx(c *fiber.Ctx) error {
        newCtx := context.WithValue(c.UserContext(), fiberCtxKeyVal, c)
        c.SetUserContext(newCtx)
        return c.Next()
    }
    
  3. 挂载路由(同方案一)

    app.Group("/graph").Use(injectFiberCtx).All(fiber.Handler(adaptor.HTTPHandler(gqlHandler)))
    
  4. 解析器中获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:00:13