GqlGen:在字段解析器中访问查询输入参数
如何在GqlGen字段解析器中访问父查询的输入参数
你遇到的这个场景很典型——GqlGen生成的字段解析器默认只提供父对象和上下文,没法直接拿到父查询的输入参数。下面给你两种实用的解决方案:
方法1:通过Context传递参数
这种方法不需要修改你的models.Main结构体,适合不想污染数据模型的场景。
首先定义一个私有的context key(避免和其他上下文值冲突):
type contextKey string const deviceKey contextKey = "device"
然后在你的Main查询解析器里,把device参数存入context:
func (r *queryResolver) Main(ctx context.Context, device string) (*models.Main, error) { // 将device参数存入context ctx = context.WithValue(ctx, deviceKey, device) // 正常创建或获取你的models.Main对象 mainObj := &models.Main{/* 初始化原有字段 */} return mainObj, nil }
接下来在Version字段解析器里,从context中取出这个值:
func (r *mainResolver) Version(ctx context.Context, obj *models.Main) (*models.Version, error) { // 从context获取device参数,注意类型断言 device, ok := ctx.Value(deviceKey).(string) if !ok { return nil, fmt.Errorf("failed to retrieve device parameter from context") } // 现在你可以用device参数做逻辑处理,比如根据设备类型返回对应版本 version := &models.Version{/* 构造对应版本数据 */} return version, nil }
方法2:扩展父模型存储参数
如果你的业务允许修改models.Main结构体,可以直接给它加一个额外字段来存储device参数:
首先修改models.Main(如果是GqlGen自动生成的,建议通过schema标记或gqlgen.yml配置来保留自定义字段,避免重新生成代码时被覆盖):
type Main struct { // 原有的业务字段... Device string `json:"device,omitempty"` // 新增字段存储device参数 }
然后在Main查询解析器里给这个字段赋值:
func (r *queryResolver) Main(ctx context.Context, device string) (*models.Main, error) { mainObj := &models.Main{ // 初始化原有业务字段 Device: device, // 把输入参数存入父对象 } return mainObj, nil }
最后在Version解析器里直接从obj获取:
func (r *mainResolver) Version(ctx context.Context, obj *models.Main) (*models.Version, error) { // 直接从父对象拿到device参数 device := obj.Device // 后续逻辑处理... version := &models.Version{/* 构造对应版本数据 */} return version, nil }
两种方法的对比
- Context方法:优点是不修改数据模型,保持模型的纯粹性;缺点是如果有多个参数需要传递,上下文会变得臃肿,且类型断言需要额外的错误处理。
- 扩展模型方法:优点是直观易懂,参数传递逻辑清晰;缺点是需要维护模型的自定义字段,若依赖GqlGen自动生成代码,需做好配置避免字段被覆盖。
内容的提问来源于stack exchange,提问作者Shashank Sachan
相关产品推荐
相关产品推荐

