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

使用gqlgen构建GraphQL API时嵌套Balance实体未解析的问题排查

gqlgen中User嵌套Balance字段Resolver未被调用、返回null的解决方法

问题根源

  1. Resolver职责混淆:你当前实现的GetBalance是顶层Query字段的Resolver,仅在直接调用getBalance(id:...)查询时才会触发。而User类型下的balance属于对象嵌套字段,需要单独实现UserResolver接口的对应方法,gqlgen才会在解析User对象时自动调用它获取关联数据。
  2. SQL查询逻辑错误:UserRepo.GetBalance使用Query处理单行查询,未调用rows.Next()就直接Scan,会导致数据读取失败,即使Resolver被触发也无法返回正确结果。

解决方案

1. 实现UserResolver的Balance字段Resolver

修改Resolver代码,新增UserResolver接口实现,专门处理User对象下的balance字段:

type Resolver struct {
    Repo *UserRepo
}

// 原有QueryResolver逻辑保留不变
func (r *queryResolver) GetUser(ctx context.Context, id int) (*model.User, error) {
    user := r.Repo.GetUser(int64(id))
    log.Println("hello")
    return &model.User{
        ID:          int(user.Id),
        Firstname:   user.Firstname,
        Lastname:    user.Lastname,
        PhoneNumber: user.PhoneNumber,
    }, nil
}

func (r *queryResolver) GetBalance(ctx context.Context, id int) (*model.Balance, error) {
    balance := r.Repo.GetBalance(int64(id))
    return &model.Balance{
        ID:           int(balance.Id),
        BalanceValue: balance.BalanceValue,
    }, nil
}

func (r *Resolver) Query() QueryResolver {
    return &queryResolver{r}
}

// 新增UserResolver相关代码
type userResolver struct{ *Resolver }

func (r *Resolver) User() UserResolver {
    return &userResolver{r}
}

// Balance方法:专门处理User类型下的balance字段查询
func (r *userResolver) Balance(ctx context.Context, obj *model.User) (*model.Balance, error) {
    // 通过当前User的ID关联查询对应的balance
    balance := r.Repo.GetBalance(int64(obj.ID))
    return &model.Balance{
        ID:           int(balance.Id),
        BalanceValue: balance.BalanceValue,
    }, nil
}

type queryResolver struct{ *Resolver }
type mutationResolver struct {
    *Resolver
}

2. 修复UserRepo的SQL查询逻辑

将Query替换为QueryRowContext(适合单行数据查询),并修正错误处理:

func (r *UserRepo) GetBalance(bid int64) *models.BalanceModel {
    balance := &models.BalanceModel{}
    query := `SELECT balance_id, balance_value FROM user_schema.balance WHERE user_id = $1`
    // 使用QueryRowContext处理单行查询,避免多行结果集的读取问题
    err := constant.Db.QueryRowContext(context.Background(), query, bid).Scan(&balance.Id, &balance.BalanceValue)
    if err != nil {
        panic(err)
    }
    return balance
}

3. 重新生成gqlgen代码

修改Resolver结构后,运行命令更新生成的代码,确保新的UserResolver接口被识别:

go run github.com/99designs/gqlgen generate

测试验证

再次发起你的查询请求:

query {
  getUser(id: 1) {
    firstname,
    lastname,
    balance {
      id,
      balanceValue
    }
  }
}

此时gqlgen会在解析User对象时自动调用Balance方法,返回关联的balance数据,不再返回null。

内容的提问来源于stack exchange,提问作者Cross

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:08:16