graphql - GraphQL 数据建模 - 扩展类型 (Prisma)
问题描述
在我的 Prisma 数据模型中,我从一个基本的用户类型开始,如下所示:
type User {
name: String!
email: String! @unique
password: String!
}
现在用户可以有两个角色:作为候选人或作为与雇主关联的用户。如果是候选人,则用户还应具有一组应用程序和一组资格,如果与雇主相关联,则它应具有访问级别和对雇主的引用。
首先,有什么方法可以扩展 GraphQL 数据建模中的基本类型?如果是这样,我将如何去做?
如果没有,我可以看到使用了三种不同的方法,我很好奇每种方法的优缺点是什么:
- 有两种不同的类型
CandidateUser
和EmployerUser
,每种类型都有字段name
,email
,password
。我发现这种方法有两个问题:@unique
标记email
不可靠,我必须编写自定义验证以确保该字段在两种类型中都是唯一的;并且拥有一个接收电子邮件并获取用户相应数据的登录功能不再是微不足道的:它需要在两个表中进行查找。
像这样:
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!
}
同样是两种不同的类型,但包含一个
RootUser
,name
andemail
,password
和CandidateUser
andEmployerUser
每个都有一个对 a 的一对一引用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! }
扩展
User
为将 EmployerUser 和 CandidateUser 中的字段作为可选参数。这是一种非常简单的方法,但我需要自定义处理来强制执行需要的字段(例如,我不能将雇主标记为必填项,因为候选人不存在该字段)。type User{ name: String! email: String! @unique password: String! applications: [Application!]! qualifications: [Qualification!]! employer: Employer accessRight: AccessRight }
我真的想问是否有更好的方法来解决这个问题。我对 GraphQL 还是很陌生,并不是最好的数据建模者,但我会非常感谢任何朝着正确方向发展的推动 :)
如果除了我列出的三个之外我别无选择,那么哪一个最有意义?
解决方案
你想要做的是实现一个接口类型:
接口是一种抽象类型,它包含一组特定的字段,类型必须包含这些字段才能实现接口。
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!]!
}
当您想要返回一个对象或一组对象时,接口很有用,但它们可能有几种不同的类型。查看接口抽象类型文档以获取更多信息。
更新:
由于这是一个 Prisma GraphQL 问题,您应该知道Prisma 还不支持接口或联合类型。问题 #83和问题 #165分别作为功能请求进行讨论。
但是,有这篇很棒的文章讨论了这种方法的解决方法:
使用 Prisma 和 Yoga 的 GraphQL 接口(和联合类型)
这归结为2个选项:
- 将所有具有可选类型特定字段的数据存储在 Prisma 中的一种类型(接口)下,然后将数据拆分回应用服务器中的原始类型之间。
- 将每个原始类型的数据存储在 Prisma 上,并在应用服务器上拼接用于查询的东西。
推荐阅读
- c++ - 为什么在我构建我的 c++ 代码时 cmake 会返回错误?
- ansible - 使用 Ansible 将 IAM 角色附加到 AWS RDS 实例
- reactjs - 跨站点 cookie 的问题:如何将 cookie 从后端设置到前端
- intellij-idea - 在 IntelliJ (mac) 中,如何在项目窗口中选择多个文件?
- javascript - Javascript中递归求和数组的修改版本
- c# - 计算除中的所有字段
- javascript - Javascript forEach 函数覆盖自身
- android - Firebase 不会在真实设备上检索数据,但在模拟器上正常工作
- java - 为什么 Override 方法仍然可以有父方法的注释?
- java - 如何从 Java 中的 arraylist api 响应中检索 jsonObjects