Нормализация данных в запросе GraphQL - PullRequest
0 голосов
/ 30 апреля 2020

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

Группы имеют поле users, которое представляет собой массив User объектов, которые в этой группе. У меня есть одно поле на root с именем groups, которое возвращает массив всех моих групп.

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

{
    groups {
        id,
        name,
        users {
            id,
            name,
            address,
            email,
            phone,
            attitude,
            job,
            favoriteQuote,
            favoriteColor,
            birthday
        }
    }
}

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

Есть ли способ получить один набор полей для первый экземпляр объекта и другой набор для каждого другого экземпляра в ответе?

Мне нужно только name, job, email et c et c один раз на пользователя в ответе, и только id после этого (впоследствии я могу сделать свою собственную нормализацию).

альтернативно

Есть ли способ получить только id поля для всех пользователей в группах и вернуть отдельный массив всех уникальных User объектов, на которые есть ссылки в запросе (что не является all User объектами)?

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Есть ли способ получить один набор полей для первого экземпляра объекта и другой набор для каждого другого экземпляра в ответе?

Нет. Один и тот же набор полей будет возвращен для каждого элемента в списке, если тип отдельного элемента не отличается, поскольку для каждого типа, возвращаемого во время выполнения, может быть указан отдельный набор выбора.

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

Можно разработать Ваша схема для размещения этого. Что-то вроде

{
  groups {
    nodes {
      id
      name
      users {
        id
      }
    }
    uniqueUsers {
      id
      # other fields
    }
  }
}

Ваш распознаватель groups должен будет обработать всю нормализацию и вернуть данные в соответствующей форме. Тем не менее, более простым решением может быть просто перевернуть ваши отношения:

{
  users {
    id
    name
    address
    email
    phone
    attitude
    job
    favoriteQuote
    favoriteColor
    birthday
    groups {
      id
      name
    }
  }
}
1 голос
/ 30 апреля 2020

Обычно - обычно

... нормализация ... конечно ... например, использование apollo и его нормализованного кэша.

Все записи, возвращаемые из API, должны быть одной и той же формы.

Вы можете получить данные и отобразить какой-либо компонент <MembersList/>, используя запрос только для идентификаторов и имен (полный / разбитый на страницы).

Позже вы можете отобразить детали в некоторый <UserProfile/> компонент с собственным запросом (хук useQuery внутри) для извлечения дополнительных данных из кэша / API (управляемый).

Ваши конкретные c требования - возможно

1-й вариант:

Обычно ответ имеет одну общую форму (в соответствии с запросом), но вы можете решить на уровне решателя, что возвращать. Это требует изменения структуры запроса, что позволяет (API, серверная часть) обнулять некоторые свойства. Например,

group {
    id
    name
    users {
        id
        name
        profile {
          photo
          email
          address

С profile нестандартным типом json ... вы можете создать распознаватель пользователей, который будет возвращать полные данные только для 1-й записи и null для всех следующих пользователей.

2-й вариант:

Вы можете использовать 2 слегка отличающихся запроса в один запрос . Используйте псевдонимы (см. Документы), вкратце:

groupWithFullMember: group ( groupId:xxx, limitUsers:1 ) {
    id
    name
    users {
        id
        name
        address
        email
        ...
    }
}

groupMembers: group ( groupId:xxx ) {
    id
    name // not required
    users {
        id
        name
    }
}

Преобразователь группы может вернуть свой дочерний элемент users ... или users resolver может получить доступ к параметру limitUsers, чтобы ограничить ответ / изменить запрос базы данных.

...