Context
我有一个GraphQL API和一个NodeJS&Angular应用程序,它有一个容纳用户的MongoDB数据库 . 对于每个用户,都有一个公共页面,其中包含 id
和 username
等公共信息 . 当用户登录时,会有一个包含 email
等扩展信息的私人资料页面 .
仅针对上下文,我使用jsonwebtoken和accesscontrol来验证和授权用户 . 信息存储在每个GraphQL解析函数的上下文中,因此可以使用任何标识登录用户的方法 .
我有一个GraphQL查询,检索公共用户,如下所示:
query getUserById($id: ID!) {
getUserById(id: $id) {
id,
username
}
}
我试图考虑正确的实现来检索公共或私人用户 . 由于GraphQL是强类型的,我在提出适当的解决方案时遇到了一些麻烦 .
Question
如何实现公共和私人用户之间的区别?
Considerations
1. Separate query
因此,其中一个选项是对公共和私有字段进行单独查询:
公共查询
query getUserById($id: ID!) {
getUserById(id: $id) {
id,
username
}
}
私人查询
query getMe {
getMe {
id,
username,
email
}
}
2. Using GraphQL Interfaces
我遇到了this Medium article,它解释了如何使用GraphQL接口根据 resolveType
函数返回不同的类型 . 所以我会这样做:
query getUser($id: ID!) {
getUser(id: $id) {
... on UserPrivate {
id,
username
}
... on UserPublic {
id,
username,
email
}
}
}
我没有找到一个合适的解决方案,我不确定到目前为止我所考虑的任何一个问题 .
任何帮助深表感谢!
1 回答
我认为你在这里缺少的是在GraphQL中你通常想要创建这个深度连接的图形结构 . 虽然
getUserById
和getMe
可以很好地作为入口点(我认为即使使用接口类型它们仍然是个好主意),但您很可能会在您的架构中出现用户类型 . 想象一下受欢迎的博客帖子示例:在这里添加两个作者字段并不能很好地工作 . 同样在您的示例中,您可能不知道配置文件页面是您自己的,直到您从后端获得响应(想想推特配置文件) .
Instead, in my opinion there are two methods to consider:
第一个是界面理念 . 您将拥有一个具有私有和公共类型的所有公共字段和具体实现的接口 . 这里很好看:如果你只使用公共字段,你甚至不必使用类型匹配:
当它变得更精细(人们分享他们希望向公众展示的内容,想象Facebook)或者你有很多类型(UserMe,UserFriend,UserStranger)时,你可能想要考虑可以为空的字段 . 如果您无权访问该字段,您将从API收到null . 要减少空值检查的数量,您可以轻松地将字段捆绑到各自的类型中(例如
Address
) .Summary:
从API点来看,返回可空字段要容易一些,因为它为您提供了很大的灵活性 . 在不破坏第一个选项的情况下,比第一个选项更容易进化第二个选项 . 如果使用静态类型(Typescript,Flow,Scala.js,Reason等),使用接口更具表现力,并且在前端工作肯定更有趣 . 关键字:模式匹配 .