GraphQL: использовать тип ввода и одно из его полей в одном запросе - PullRequest
1 голос
/ 23 февраля 2020

Мне интересно, как использовать тип ввода и одно из его полей в качестве аргументов в одном и том же запросе GraphQL. Я думаю, что есть несколько правильных решений, но мне интересно, какие (если таковые имеются) являются лучшей практикой.

Рассмотрим следующий гипотетический запрос. Мы получаем игроков по местоположению и статусу, а также членов команды, которые находятся в одном месте, но поле member имеет только аргумент location:

input PlayerInput {
  location: String!
  status: Int!
}

query getPlayers($playerInput: PlayerInput) {
  players(playerInput: $playerInput) {
    name
    team {
      name
      members(location: ???) { // <-- How to access playerInput.location?
        name
      }
    }
  }
}

Я могу придумать несколько способов решить это:

1. Измените запрос так, чтобы он принимал отдельные аргументы

query getPlayers($location: String!, $status: Int!) {
  players(playerInput: { location: $location, status: $status }) {
    name
    team {
      name
      members(location: $location) {
        name
      }
    }
  }
}

2. Обновите схему так, чтобы members принимал правильный тип ввода

query getPlayers($playerInput: PlayerInput) {
  players(playerInput: $playerInput) {
    name
    team {
      name
      members(playerInput: $playerInput) { // <-- Requires changing schema
        name
      }
    }
  }
}

Это не кажется хорошим по нескольким причинам и сработало бы, только если у вас есть возможность обновить схему.

3. Передайте location в качестве избыточного отдельного аргумента

query getPlayers($playerInput: PlayerInput, $location: String!) {
  players(playerInput: $playerInput) {
    name
    team {
      name
      members(location: $location) {
        name
      }
    }
  }
}

Это выглядит нормально, просто при создании запроса есть некоторое дублирование:

const location = 'US';
const status = 1;

fetch({
  query: getPlayersQuery,
  variables: {
    location,
    playerInput: {
      location,
      status,
    }
  }
})...

Любой из этих предпочтительный способ сделать что-то вроде этого? Есть ли другие способы, которые я не рассмотрел?

1 Ответ

3 голосов
/ 24 февраля 2020

Использование нескольких аргументов для одного аргумента, который принимает тип ввода (опция # 1), иногда имеет смысл концептуально , но в нем отсутствуют какие-либо другие реальные достоинства и есть обратная сторона в том, что определения переменных излишне многословны. На мой взгляд, использование типов ввода, как правило, также обеспечивает более эффективную типизацию. Изменение схемы просто для того, чтобы избежать дублирования, не стоит.

Использование одного и того же типа входного объекта в обоих полях (опция # 2) следует выполнять только в том случае, если оба поля действительно требуют всех этих полей ввода. Делать это просто, чтобы избежать дублирования, - плохая идея - он эффективно вводит неиспользуемые входные данные, что не очень удобно для любого другого разработчика, использующего API.

Вариант № 3 - это хорошо. Он также помещает мяч во двор внешнего разработчика - если бы они хотели , чтобы избежать дублирования, они могли бы также легко сделать это, не вводя дополнительные аргументы:

query getPlayers($status: Int!, $location: String!) {
  players(playerInput: { status: $status, location: $location }) {
    name
    team {
      name
      members(location: $location) {
        name
      }
    }
  }
}

Тем не менее, дублирование, скорее всего, на самом деле хорошо. Вы не встречаете этот сценарий ios слишком много в дикой природе, потому что мы имеем дело с графиками данных. Поля players, team и members являются частью иерархии, где родительское поле ограничивает данные, возвращаемые дочерним элементом - например, members не возвращает все элементы, только элементы этого конкретная команда. Это означает, что в большинстве случаев , если вы ограничиваете players только для включения данных из определенного местоположения, вы также ограничиваете данные, возвращаемые дочерними полями, такими как members. Если вы чувствуете, что members нужен собственный аргумент location, , то это означает, что два входных местоположения могут отличаться . Если они могут отличаться, они должны быть представлены в виде двух отдельных переменных для обеспечения максимальной гибкости и повторного использования запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...