Однократный запрос gorm и graphql - PullRequest
0 голосов
/ 02 августа 2020

Итак, у меня есть вот эта модель плеера:

package models

// Player defines a player for the app
type Player struct {
    BaseModelSoftDelete
    Name                *string
    Nickname            *string
    ThrowCount          *int
    InGame              *bool
    // Belongs to one
    GameID *int
    // Has one
    Image    Image
    X01Score X01Score
    Podium   Podium
    // Has many
    Rounds []Round
}

И у меня работает GraphQL с этой схемой:

type Player {
  id: ID!
  name: String!
  nickname: String
  throwCount: Int
  inGame: Boolean
  gameId: ID
  game: Game
  image: Image
  x01score: X01Score
  podium: Podium
  rounds: [Round]
}

type Query {
  playerList: [Player]
  player(id: ID!): Player
}

GraphQL используется для представления моих данных. У меня есть два типа преобразователей запросов. Преобразователь списков, который должен возвращать список, который работает следующим образом:

func (r *queryResolver) PlayerList(_ context.Context) ([]*models.Player, error) {
    var players []*models.Player
    r.ORM.DB.Preload("Game").Preload("Image").Preload("Podium").Preload("X01score").Preload("Rounds").Preload("Rounds.Throws").Find(&players)

    return players, nil
}

Посмотрите, как переменная player является срезом типа models.Player? И возвращаемое значение тоже единица? Все идет нормально. Это вернет моих игроков, как и предполагалось.

Теперь у меня есть второй тип, который должен возвращать одного игрока в зависимости от его ID:

func (r *queryResolver) Player(_ context.Context, id int) (*models.Player, error) {
    var player *models.Player
    r.ORM.DB.Preload("Image").Preload("X01score").Preload("Game").Preload("Podium").First(&player, id)

    return player, nil
}

Посмотрите, как gqlgen определил возвращаемое значение быть единственным экземпляром models.Player? Также я определяю переменную как единственный экземпляр и возвращаю ее. Ну, код будет скомпилирован, но если я запрошу игрока с идентификатором 1 (игрок находится в базе данных, я проверил его с помощью браузера sqlite), он вернет ошибку, которая гласит:

unsupported destination, should be slice or struct

в строке, запрашивающей игрока -> ... First (& player, id)

Итак, я могу обойти проблему, определив схему следующим образом:

type Query {
  playerList: [Player]
  player(id: ID!): [Player]
}

Я изменил запрос плеера, чтобы он возвращал массив в определении схемы. Затем определите преобразователь следующим образом:

func (r *queryResolver) Player(_ context.Context, id int) ([]*models.Player, error) {
    var player []*models.Player
    r.ORM.DB.Preload("Image").Preload("X01score").Preload("Game").Preload("Podium").First(&player, id)

    return player, nil
}

Измененная переменная на срез, а также возвращаемое значение. Gorm запросит только одно возвращаемое значение (причина ... First (& player, id)) из базы данных и упакует его в фрагмент всего с одной записью.

Мне это кажется неправильным. Как я могу решить эту проблему?

С уважением и наилучшими пожеланиями, Патрик

Решение, приведенное в предложении ниже:

Спасибо, Саймон С.

func (r *queryResolver) Player(_ context.Context, id int) (*models.Player, error) {
    var player models.Player
    r.ORM.DB.Preload("Image").Preload("X01score").Preload("Game").Preload("Podium").First(player, id)

    return &player, nil
...