Как передать параметр фрагменту graphql?

#react-native #graphql

#react-native #graphql

Вопрос:

Легко передать параметр в запрос GraphQL. Но как насчет фрагментов GraphQL?

Этот код содержит несколько совершенно обычных запросов с параметром (ItemId) и подсказку о том, что я пытаюсь сделать (includeExtraResults) :

 export const GET_ITEM = gql`
  query GetItem($itemId: ID!, $includeExtraResults:BOOLEAN) {
    container {
      item(itemId: $itemId) {
        itemId
        someField
        innerItem(someExtraOption: $includeExtraResults) {
          ...InnerItemFragment
        }
      }
    }
  }
  ${INNER_ITEM_FRAGMENT}
`;

export const INNER_ITEM_FRAGMENT = gql`
  fragment InnerItemFragment on InnerItemType {
    innerItemId
    innerInnerItem(someExtraOption: $includeExtraResults) {
      someFields
    }
  }
  ${INNER_INNER_ITEM_FRAGMENT}
`;


export const INNER_INNER_ITEM_FRAGMENT = gql`
  /* (not detailed here) */
`;
  

Когда внутренние элементы автоматически запрашиваются как часть внутренних элементов, я не хочу, чтобы они возвращали поле, на основе которого работает фильтр. Клиент также не знает логики. Вместо этого я хочу использовать параметр, а логика определяется на стороне сервера.

Тем не менее, их запрос реализован таким образом, что ему требуется (необязательный) параметр «includeExtraResults», который передается в GetItem в первую очередь.

Итак, есть ли способ передать «includeExtraResults» во внутренний фрагмент? Что следует изменить, чтобы это имело смысл? В реальной жизни это сложная система со многими уровнями внутренних фрагментов.

Ответ №1:

Вы можете использовать переменные запроса внутри фрагментов:

 query HeroComparison($first: Int = 3) {
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  friendsConnection(first: $first) {
    totalCount
    edges {
      node {
        name
      }
    }
  }
}
  

Эта информация из официального руководства

Комментарии:

1. На самом деле я пытался добиться именно этого, поэтому я заменил «правильный ответ» на ваш ответ (спустя почти 3 года после того, как в другом ответе была зеленая галочка;-p). Я не помню, почему я сталкивался с проблемами и что заставило меня поверить, что я не могу использовать глобальный параметр запроса во фрагменте. Возможно, я использовал некоторые автоматически сгенерированные оболочки Typescript и / или какой-либо инструмент проверки синтаксиса (Lint), который выдавал красные флаги по этому поводу. Или, может быть, у меня просто не хватило смелости предположить, что это сработает.

Ответ №2:

Как описано здесь, вы должны явно включить переменные фрагмента перед их использованием:

 import { enableExperimentalFragmentVariables } from 'graphql-tag'

enableExperimentalFragmentVariables()
  

Это, по крайней мере, должно позволить вам использовать переменные, определенные в вашей операции, внутри включенных фрагментов. Пожалуйста, обратите внимание, что это все еще экспериментальная функция, которая официально не является частью спецификации — смотрите Этот выпуск для продолжения обсуждения.

Комментарии:

1. Не могли бы вы добавить пример для демонстрации синтаксиса прямо здесь, в stackoverflow?

2. @jeancallisti Вышеуказанное должно работать с кодом в вашем вопросе. Кроме включения функции, никаких изменений не требуется. Что неясно в синтаксисе?

3. Тогда хорошо, если это работает «как есть» и если includeExtraResults можно передать во innerInnerItem, тогда все в порядке. Интересно, как отреагирует компилятор, если я включу этот фрагмент в другой запрос, в котором нет параметра, но это на другой день.

4. Я думаю, graphql-tag это все равно будет проанализировано, но вы определенно столкнетесь с ошибкой сервера, поскольку ваш запрос не пройдет проверку.