【问题标题】:GraphQL data modelling - extended types (Prisma)GraphQL 数据建模 - 扩展类型 (Prisma)
【发布时间】:2019-02-14 19:28:52
【问题描述】:

在我的 Prisma 数据模型中,我从一个基本的用户类型开始,如下所示:

type User {
  name: String!
  email: String! @unique
  password: String!
}

现在用户可以有两个角色:作为候选人或作为与雇主关联的用户。如果是候选人,则用户还应该有一组应用程序和一组资格,如果与雇主相关联,则它应该具有访问级别和对雇主的引用。

首先,有什么方法可以扩展 GraphQL 数据建模中的基本类型?如果是这样,我将如何去做?

如果没有,我可以看到使用了三种不同的方法,我很好奇每种方法的优缺点是什么:

  1. 有两个单独的类型CandidateUserEmployerUser,每个类型都有nameemailpassword 字段。我发现这种方法有两个问题:email 上的 @unique 标记不可靠,我必须编写自定义验证以确保该字段在两种类型中都是唯一的;并且拥有一个接收电子邮件并获取用户相应数据的登录功能不再是微不足道的:它需要在两个表中进行查找。

像这样:

    type CandidateUser {
      name: String!
      email: String! @unique
      password: String!
      applications: [Application!]!
      qualifications: [Qualification!]!
    }
    type EmployerUser{
      name: String!
      email: String! @unique
      password: String!
      employer: Employer!
      accessRight: AccessRight!
    }
  1. 又是两种不同的类型,但RootUser 包含nameemailpassword,以及CandidateUserEmployerUser,每个类型都具有对RootUser 的一对一引用.这将在电子邮件字段上强制使用@unique 标记,但查找仍然很重要。

    type RootUser{
      name: String!
      email: String! @unique
      password: String!
    }
    type CandidateUser {
      rootUser: RootUser!
      applications: [Application!]!
      qualifications: [Qualification!]!
    }
    type EmployerUser{
      rootUser: RootUser!
      employer: Employer!
      accessRight: AccessRight!
    }
    
  2. 扩展 User 以将 EmployerUser 和 CandidateUser 中的字段作为可选参数。这是一种非常简单的方法,但我需要自定义处理来强制执行需要的字段(例如,我不能将雇主标记为必填项,因为候选人不存在该字段)。

    type User{
      name: String!
      email: String! @unique
      password: String!
      applications: [Application!]!
      qualifications: [Qualification!]!
      employer: Employer
      accessRight: AccessRight
    }
    

我真的想问是否有更好的方法来解决这个问题。我对 GraphQL 还是很陌生,并不是最好的数据建模者,但我会非常感谢任何朝着正确方向发展的推动 :)

如果除了我列出的三个之外我别无选择,哪一个最有意义?

【问题讨论】:

    标签: graphql data-modeling prisma-graphql


    【解决方案1】:

    您要做的是实现interface type

    接口是一种抽象类型,它包含一组特定的字段,类型必须包含这些字段才能实现接口。

    interface User {
      name: String!
      email: String! @unique
      password: String!
    }
    

    这意味着任何实现User 的类型都需要具有这些确切的字段,以及这些参数和返回类型。所以现在你的Candidate 类型可以实现User

    type Candidate implements User {
      name: String!
      email: String! @unique
      password: String!
      applications: [Application!]!
      qualifications: [Qualification!]!
    }
    

    当您想要返回一个对象或一组对象时,接口很有用,但它们可能有几种不同的类型。请查看interface abstract type documentation 了解更多信息。


    更新:

    由于这是一个 Prisma GraphQL 问题,您应该知道Prisma 还不支持接口或联合类型Issue #83issue #165 分别作为功能请求进行讨论。

    但是,有一篇很棒的文章讨论了这种方法的解决方法:

    GraphQL Interfaces (and Union Types) with Prisma and Yoga

    归结为 2 个选项:

    1. 将所有具有可选类型特定字段的数据存储在 Prisma 中的一种类型(接口)下,然后在应用服务器中的原始类型之间拆分数据。
    2. 将每种原始类型的数据存储在 Prisma 上,并在应用服务器上拼接以供查询。

    【讨论】:

    • 因此,如果 Candidate 和 EmployerUser 都实现了 User,电子邮件:String! @unique 是否会强制该电子邮件在 Candidates 和 EmployerUser 之间是唯一的,或者仅在每个字段中?
    • 哦,我现在明白了 Prisma 不支持接口,所以我想我还是卡住了
    • @LarsHoldaas 我想你问的是一个简单的 GraphQL 问题。 (我刚刚添加了 prisma 标签),这里讨论了 prisma-graphql 问题的接口类型:issue #83。这个问题应该有一些解决方法。
    • 无论如何,这是一个很好的答案!我认为我的问题是一个通用的 GraphQL 问题,直到我阅读了你的答案然后发现 Prisma 不支持它,所以这就是我自己没有标记它的原因。对于以后的问题,我应该记住这一点。
    猜你喜欢
    • 2019-07-23
    • 2019-12-31
    • 2019-03-13
    • 2019-12-29
    • 2018-08-01
    • 2012-09-06
    • 2020-10-18
    • 2019-12-19
    • 2023-03-11
    相关资源
    最近更新 更多