Как обрабатывать список внутри соединения в Graphql Relay

У меня есть такая схема:

type SectionItem = {
  a: String
}

type SectionRowConnection {
  pageInfo: PageInfo!
  edges: [SectionRowEdge]
}

type SectionRowEdge {
  node: [SectionItem]
  cursor: String!
}

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

query {
  sectionRows(type:someType){
    edges{
      node{
        a
      }
    }
  }
}

Теперь я использую Relay в клиенте, но получаю эту ошибку при попытке построить запрос с помощью relay:

ERROR: Encountered 1 error(s): - @connection used on invalid field sectionRows. Expected the field type SectionRowConnection to have an edges { node } field that returns an object, interface, or union.

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
0
0
349
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

От реле спец.:

An “Edge Type” must contain a field called node. This field must return either a Scalar, Enum, Object, Interface, Union, or a Non‐Null wrapper around one of those types. Notably, this field cannot return a list.

Другими словами, SectionRowConnection не соответствует требованиям Relay к типу подключения, потому что его поле узла является списком. Для этого нет обходного пути, кроме изменения вашей схемы, чтобы тип node был SectionItem! вместо [SectionItem]. Если вы хотите использовать Relay, ваша схема должна соответствовать спецификации Relay.

Само соединение представляет собой набор отдельных узлов (или «ресурсов», если использовать терминологию REST), где каждое ребро соединяет корневой узел с отдельным узлом в наборе.

Например, мы можем представить один узел User, который имеет поле friends, возвращающее UserConnection. Каждое ребро в соединении будет представлять связь между исходным узлом User и одним из друзей-пользователей. Каждое ребро будет иметь один узел пользователя.

Эта коллекция пользовательских узлов может быть естественно отсортирована и отфильтрована по мере необходимости. Однако, если бы мы хотели группа их вместе в соответствии с некоторыми критериями (аналогично GROUP BY в SQL), мы бы создали отдельный тип UserGroup и UserGroupConnection. Каждый узел UserGroup внутри UserGroupConnection сам будет иметь некоторое поле, которое является UserConnection. Даже в этом сценарии каждое ребро соединения по-прежнему имеет только один узел.

Только из вашей схемы неясно, пытались ли вы просто фильтровать или «группировать» свои узлы, как показано выше. В любом случае, концептуально нет причин, чтобы ребро когда-либо возвращало список для своего поля node.

Вот сценарий: приложение похоже на магазин, домашняя страница может содержать много строк (связь здесь), и каждая строка имеет список элементов, что-то вроде раздела приложений в магазине приложений, поэтому в этом случае Самая простая идея - иметь соединение списков, но реле этого не позволяет.

Mo Ganji 09.07.2019 15:12
Ответ принят как подходящий

В итоге я обернул список результатов внутри объекта, то есть каждый узел имеет тип SectionRow, который представляет собой graphQlObjectType с полем items, список находится внутри списка элементов. вот результирующая схема:

type SectionItem = {
  a: String
}

type SectionRow = {
  items: [SectionItem]
}

type SectionRowConnection {
  pageInfo: PageInfo!
  edges: [SectionRowEdge]
}

type SectionRowEdge {
  node: SectionRow
  cursor: String!
}

Другие вопросы по теме