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]**
    }

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

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

Спасибо

1 ответ

Решение

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

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

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

Который, если я добавлю комментарий, публиковать обновление всей доски невероятно неэффективно

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

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

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

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

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

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

type NestedObject {
  title: String
  content: String
}

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

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

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

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

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