忽略gorm / graphql中预加载

jjhzyzn0  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(179)

我目前正在通过一些关于用gqlgen和gorm(mysql服务器)创建Graphql服务器的教程。
这是我的代码

type Player struct {
    ID     string `json:"id"`
    Name   string `json:"name"`
    TeamID int    `json:"team_id"`
}

type Team struct {
    ID      string    `json:"id"`
    Nat3    string    `json:"nat3"`
    Players []*Player `json:"players"`
}

...

func (r *queryResolver) Teams(ctx context.Context) ([]*model.Team, error) {
    var teams []*model.Team
    r.DB.Preload("Players").Find(&teams)

    return teams, nil
}

所以通过请求“teams with player”就可以了。但是我想知道是否有一种方法可以跳过Players的预加载,当players不是graphql客户端请求的时候,就像这样:

query{
    teams {
        id
        nat3
    }
}

上面我没有请求players,但是执行了预加载,这在mysql服务器上产生了不必要的负载。

toe95027

toe950271#

对于players,你需要一个额外的解析器。这是GraphQL的一个通用概念,而不是Go语言和gqlgen语言的特定概念。
在gqlgen中,你可以为gqlgen.yml文件中的特定字段指定一个解析器。这里应该有一个models属性。如果还没有,你可以添加它。

# top-level property
models:
  # name of your Go type
  Team:
    # fields, don't change this
    fields:
      # name of the field for which you want a resolver
      players:
        resolver: true

然后使用go run github.com/99designs/gqlgen重新生成Go代码,或者如果按照gqlgen项目的设置,则只使用go generate
现在应该会在某处生成Team的解析器类型,如下所示:

func (r *resolver) Team() schema.TeamResolver {
    return &teamResolver{r}
}

type teamResolver struct {
    *resolver // this should be the gqlgen root resolver
}

和它的Players解析器,如下所示:

func (r *teamResolver) Players(ctx context.Context, obj *model.Team) ([]*model.Player, error) {
    // fetch players here
}

现在,如果客户端请求不包含players,则此解析程序将不会运行。

相关问题