【问题标题】:Graphql schema design problem that I can't solve我无法解决的 Graphql 架构设计问题
【发布时间】:2021-01-07 18:48:44
【问题描述】:

我正在尝试为应用程序设计架构,但我遇到了无法解决的问题。这是应用程序的详细信息

用户 A 喜欢用户 B 用户 B 匹配用户 B 现在用户 A 和用户 B 可以开始互相聊天了。

我还会跟踪谁访问了每个个人资料 用户 B 访问了用户 A 用户 C 访问了用户 A

在应用程序中,我输入了运行应用程序的用户的详细信息。我有一个看起来像这样的 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,因此如果关系在多个地方重复,这将是一个问题。

我非常感谢任何帮助,因为我没有想法。

提前致谢。

【问题讨论】:

    标签: graphql graphql-schema


    【解决方案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
          }
        }
      }
    }
    

    您的应用程序的解析器代码需要填写这些对象引用。

    【讨论】:

    • 大卫,感谢您的帮助。我知道你所说的。我唯一关心的是用户之间的关系。我在哪里把它放在架构中。该关系应该在客户端可以兑现,因为它可以由用户更改。谢谢
    • 在我上面展示的示例模式中,User 对象类型有一个likes 字段,其值是其他User 对象的列表。就是这样的关系。如果您认为这将是一个大型集合,则可以使用诸如 Relay connection pattern 之类的扩展模式,其中包括分页和其他功能。
    • 暂时忘掉 Me 查询,想想 listUsers 搜索查询,它应该会为您提供如上所述的结果。您在此查询中将关系放在哪里?每当我查看用户列表时,我都想知道该用户与我自己之间的关系。这同样适用于访问过我的人员列表。
    • 我想我有点不清楚你所说的“关系”是什么意思。您是指任何类型的对象之间的任何连接(如 SQL 外键,或 ORM 中的“具有多”关系)?或者任何这些类型的“用户 A 连接到用户 B”链接?你想要任何类型的连接的抽象概念吗?反向遍历这些链接的能力(“谁喜欢这个用户”)?
    • 用户之间的关系是多对多的关系。所以用户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-关系实际上不是用户(节点)的一部分,而是应该是边缘的一部分。 2-我不得不太担心user.source。所以我决定把这段关系推到边缘。实现变得更好,但必须做更多更多的代码。所以,我想我会去看看其他开发者怎么说。
    猜你喜欢
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2023-04-06
    • 2020-08-05
    相关资源
    最近更新 更多