Проблема проектирования схемы Graphql, которую я не могу решить

#graphql #graphql-schema

#graphql #graphql-схема

Вопрос:

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

Пользователь A ЛЮБИТ пользователя B Пользователь B СООТВЕТСТВУЕТ пользователю B Теперь пользователь A и пользователь B могут начать общаться друг с другом.

Я также отслеживаю, кто посетил каждого пользователя профиля A, КОТОРОГО ПОСЕТИЛ пользователь B, Пользователя A, которого посетил пользователь C

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

 me {
  id
  name
  email
  ...
  ...
  likes {  ## users who liked me
    nextToken
    edges {
      node { ## user
        id
        name
        ...
      }
    }
  }
  matchs { ## users who matched with me
    nextToken
    edges {
      node { ## user
        id
        name
        ...
        ...
      }
    }
  } 
  Vists { ## users who visited me
    nextToken
    edges {
      node { ## 
        id
        name
        ...
        ...
      }
    }
  }
}
  

В дополнение к этому у меня есть запрос ListUsers, который перечисляет пользователей поблизости от меня и выглядит примерно так:

 listUsers {
  nextToken
  total
  edges {
    distance
    node {  ## user
      id
      name
      ...
      ...
    }
  }
}
  

МОЙ ВОПРОС
Поскольку между пользователями существует связь (LIKED_BY, MATCHED_WITH), где я могу использовать эту связь в своей схеме, чтобы ее можно было обналичить. Имейте в виду, что отношения могут меняться на клиенте с NO_RELATIONSHIP на LIKED_BY на MATCHED_WITH, поэтому, если отношения дублируются в нескольких местах, это будет проблемой.

Я был бы очень признателен за любую помощь, поскольку у меня нет идей.

Заранее спасибо.

Ответ №1:

В схеме GraphQL вы обычно делаете ссылки, подобные этим, явными ссылками на другой объект.

 type User {
  id: ID!
  ...
  matches: [User!]  # actual users, not their IDs
  likes: [User!]
  visitedBy: [User!]
}
  

В вашем Query типе верхнего уровня вы можете вернуть текущего пользователя

 type Query {
  me: User
}
  

Теперь, если мне нужны имена и адреса электронной почты людей, которые посетили меня, я могу узнать

 query WhoVisitedMe {
  me {
    visitedBy { name, email }
  }
}
  

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

 query WhoDoVisitorsLike {
  me {
    visitedBy {
      likes {
        id
        name
      }
    }
  }
}
  

Код вашего приложения-преобразователя должен будет заполнить эти ссылки на объекты.

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

1. Дэвид, спасибо за вашу помощь. Я в курсе того, что вы сказали. Меня беспокоят только отношения между пользователями. Где мне разместить его в схеме. Связь должна быть обналичиваемой на стороне клиента, потому что она может изменяться пользователями. Спасибо

2. В примере схемы, который я показал выше, User тип объекта имеет likes поле, значением которого является список других User объектов. Это взаимосвязь. Существуют расширенные шаблоны, такие как шаблон подключения к реле , которые включают разбивку на страницы и другие функции, если вы считаете, что это будет большая коллекция.

3. Забудьте на секунду о запросе Me и подумайте о поисковом запросе ListUsers, который должен дать вам результаты, как описано выше. Где вы размещаете связь в этом запросе? Всякий раз, когда я просматриваю список пользователей, я хотел бы знать отношения между этим пользователем и мной. То же самое относится и к списку людей, которые посетили меня.

4. Я думаю, мне немного непонятно, что вы подразумеваете под «отношениями» здесь. Вы имеете в виду какую-либо связь между любыми типами объектов (например, внешним ключом SQL или отношением «имеет много» в ORM)? Или любой из этих типов ссылок «пользователь A подключен к пользователю B»? Вам нужно абстрактное понятие какого-либо соединения? Возможность обхода этих ссылок в обратном порядке («кому нравится этот пользователь»)?

5. Отношения между пользователями — это отношения «многие ко многим». Итак, пользователю A нравится много пользователей, и многим пользователям может понравиться пользователь A. Перечисляя пользователей в поисковом запросе, мне нужно иметь возможность знать отношения между мной и пользователями, чтобы я мог сказать, чтобы мне нравились или совпадали пользователи. Кроме того, если я знаю отношения между мной и пользователем, я могу показать значок для пользователя, чтобы указать отношения.

Ответ №2:

Вы уточнили в комментарии:

При перечислении пользователей в поисковом запросе мне нужно знать отношения между мной и пользователями

То есть вы пытаетесь спросить о каком-то пользователе

 type User {
  relationToMe: [RelationshipType!]
}
  

relationToMe Поле может иметь любое количество (включая ноль) типов отношений; вы можете определить их как перечисление GraphQL

 enum RelationshipType {
  LIKES, LIKED_BY,
  VISITED, VISITED_BY,
  MATCHES               # bidirectional
}
  

Затем в своем запросе вы можете спросить

 query FindSomeUsers($input: SearchUsersInput!) {
  searchUsers(input: $input) {
    users {
      id, name, email
      relationToMe
    }
  }
}
  

и получите ответ, подобный

 {
  "data": {
    "searchUsers": {
      "users": [
        "id": "12345",
        "name": "John Smith",
        "email": "jsmith@example.com",
        "relationToMe": ["VISITED", "MATCHES"]
      ]
  }
}
  

Вам нужно будет внедрить пользовательский распознаватель в вашей реализации, чтобы заполнить это поле. Если у вас есть что-то вроде таблицы соединений SQL «многие ко многим», вы можете запросить ее для заполнения этого поля, если потребуется.

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

1. В прошлом я устанавливал связь с пользователем, но столкнулся с парой проблем. 1-отношение на самом деле не является частью пользователя (узла), а скорее должно быть частью ребра. 2- Мне приходится слишком беспокоиться о user.source. Поэтому я решил перенести отношения в edge. Реализация стала лучше, но пришлось сделать гораздо больше кода. Итак, я подумал, что проверю и посмотрю, что скажут другие разработчики.