GraphQL: Как сделать схему вложенной?

В прошлом году я преобразовал приложение для использования Graphql. До сих пор это было здорово, во время преобразования я по сути перенес все свои службы, которые поддерживали мои конечные точки REST, для поддержки запросов и мутаций grapqhl. Приложение работает хорошо, но я хотел бы продолжить развитие своего графа объектов.

Допустим, у меня есть следующие отношения.

Пользователь -> Команда -> Доски -> Списки -> Карты -> Комментарии

В настоящее время у меня есть две разные вложенные схемы: Пользователь -> команда:

    type User {
  id: ID!
  email: String!
  role: String!
  name: String!
  resetPasswordToken: String
  team: Team!
  lastActiveAt: Date
}

type Team {
  id: ID!
  inviteToken: String!
  owner: String!
  name: String!
  archived: Boolean!
  members: [String]
}

Затем у меня есть Доски -> Списки -> Карты -> Комментарии.

type Board {
  id: ID!
  name: String!
  teamId: String!
  lists: [List]
  createdAt: Date
  updatedAt: Date
}

type List {
  id: ID!
  name: String!
  order: Int!
  description: String
  backgroundColor: String
  cardColor: String
  archived: Boolean
  boardId: String!
  ownerId: String!
  teamId: String!
  cards: [Card]
}

type Card {
  id: ID!
  text: String!
  order: Int
  groupCards: [Card]
  type: String
  backgroundColor: String
  votes: [String]
  boardId: String
  listId: String
  ownerId: String
  teamId: String!
  comments: [Comment]
  createdAt: Date
  updatedAt: Date
}

type Comment {
  id: ID!
  text: String!
  archived: Boolean
  boardId: String!
  ownerId: String
  teamId: String!
  cardId: String!
  createdAt: Date
  updatedAt: Date
}

Что отлично работает. Но мне любопытно, насколько я могу действительно сделать свою схему вложенной. Если бы я добавил остальное, чтобы сделать график полным:

type Team {
      id: ID!
      inviteToken: String!
      owner: String!
      name: String!
      archived: Boolean!
      members: [String]
      **boards: [Board]**
    }

Это позволило бы получить гораздо более глубокий график. Однако меня беспокоило, насколько сложными будут мутации. Специально для схемы доски вниз мне нужно публиковать обновления подписки для всех действий. Что, если я добавлю комментарий, опубликовать все обновление доски невероятно неэффективно. Хотя построенная логика подписки для каждого создания / обновления каждой вложенной схемы кажется тонной кода для достижения чего-то простого.

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

Спасибо

Кто использует ваш API? Похоже, это единый клиент, который вы тоже разрабатываете. Если вы знаете, какой клиент или клиенты используют ваш API, нужны ли этим клиентам функциональные возможности, обеспечиваемые, например, добавлением поля boards в тип Team?

Daniel Rearden 31.12.2018 13:30

«Что, если я добавлю комментарий, публикация всего обновления доски будет невероятно неэффективной». Не могли бы вы пояснить, почему вы публикуете всю доску при добавлении комментария? Я могу представить, что добавление комментария должно приводить только к публикации по какой-то подписке на commentAdded. Если card имеет поле comments, клиент должен позаботиться об обновлении этого поля с помощью writeQuery, а не полагаться на публикуемый card. Я что-то упускаю?

Daniel Rearden 31.12.2018 13:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
2
6 232
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

GraphQL руководства по стилю предлагает вам иметь все сложные структуры в отдельных типах объектов (как у вас, комментарий, команда, доска ...). Тогда вам решать, как сделать сложный запрос / мутацию.

Я бы хотел, чтобы вы расширили это предложение

Which if I add a comment, publish the entire board update is incredibly inefficient

Я не уверен в этом, так как у вас есть идентификатор карты. Таким образом, добавление нового комментария вызовет мутацию, которая создаст новую запись комментария и обновит карточку новым комментарием.

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

Взгляните, например, на GitHub GraphQL API:

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

В дополнение к общему пониманию подходов к разработке мутаций я бы предложил этот статья.

Не совсем уверен, почему это не обновило меня, извините за задержку ответа. Опубликованная вами статья о моделировании мутаций GraphQL была действительно хорошим прочтением. Имеет большой смысл ... На самом деле я просто отправлял тип JSON для обновлений, потому что я не хотел писать мутацию для каждого поля. В заключение я думаю, что самое большое, что мне кажется привычным для меня, - это часть подписок. У меня может быть этот удивительный запрашиваемый граф объектов, но необходимость создания двух обработчиков подписок на каждый объект кажется странной. Может быть, какие-то фреймворки помогут, желание может передать вариант мутации или что-то в этом роде

sauce 06.01.2019 21:44

Вы можете использовать вложенность в GraphQL, например

type NestedObject {
  title: String
  content: String
}

type MainObject {
  id: ID!
  myObject: [NestedObject]
}

В приведенном выше коде определение типа NestObject вводится в массив myObject. Чтобы лучше понять, вы можете увидеть это как:

type MainObject {
  id: ID!
  myobject: [
    {
      title: String
      content: String
    }
  ]
}

Надеюсь, это решит вашу проблему!

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