GraphQL - 如何区分 Public 和私有字段?
GraphQL - How to distinguish Public from Private fields?
上下文
我有一个 GraphQL API 和一个 NodeJS & Angular 应用程序,带有一个 MongoDB 数据库来保存用户。对于每个用户,都有一个 public 页面,其中包含 public 信息,例如 id
和 username
。用户登录后,会出现一个私人资料页面,其中包含 email
.
等扩展信息
仅供参考,我正在使用 jsonwebtoken with accesscontrol 对用户进行身份验证和授权。该信息存储在每个 GraphQL 解析函数的上下文中,因此可以使用识别登录用户所需的任何信息。
我有一个 GraphQL 查询可以像这样检索 public 用户:
query getUserById($id: ID!) {
getUserById(id: $id) {
id,
username
}
}
我正在考虑检索 public 或私人用户的正确实现。由于 GraphQL 是强类型的,我在想出一个合适的解决方案时遇到了一些麻烦。
问题
如何区分public和私人用户?
注意事项
1.单独查询
因此,其中一种选择是对 public 和私有字段进行单独查询:
public查询
query getUserById($id: ID!) {
getUserById(id: $id) {
id,
username
}
}
私人查询
query getMe {
getMe {
id,
username,
email
}
}
2。使用 GraphQL 接口
我遇到了 this Medium article,它解释了 GraphQL 接口如何用于 return 基于 resolveType
函数的不同类型。所以我会这样做:
query getUser($id: ID!) {
getUser(id: $id) {
... on UserPrivate {
id,
username
}
... on UserPublic {
id,
username,
email
}
}
}
我还没有找到合适的解决方案,我不确定我目前的任何考虑。
非常感谢任何帮助!
我认为您在这里缺少的是,在 GraphQL 中,您通常想要创建这种深度连接的图形结构。虽然 getUserById
和 getMe
作为入口点工作得很好(而且我认为即使使用接口类型它们仍然是一个好主意),但您很可能会在整个架构中出现用户类型。想象一下热门博客post例子:
type Post {
id: ID!
title: String!
content: String!
author: User!
}
在这里添加两个作者字段并不是很好。同样,在您的示例中,您可能不知道个人资料页面是您自己的,直到您收到后端的响应(想想 Twitter 个人资料)。
相反,在我看来有两种方法可以考虑:
第一个是界面的想法。您将拥有一个接口,其中包含私有和 public 类型的所有公共字段和具体实现。这里的好处是:如果您只使用公共字段,您甚至不必使用类型匹配:
query getUser($id: ID!) {
getUser(id: $id) {
id
username
# if you need a private field you can branch off here
... on UserPrivate {
email
}
}
}
当它变得更细粒度时(人们分享他们想要公开给 public 的内容,想象一下 Facebook)或者你有很多类型(UserMe、UserFriend、UserStranger)你可能想要考虑 nullable字段代替。如果您无权访问该字段,您将从 API 收到空值。为了减少 null 检查的数量,您可以轻松地将字段捆绑到它们自己的类型中(例如 Address
)。
总结:
从 API 点开始,return 可为 null 的字段更容易一些,因为它为您提供了很大的灵活性。与第一个相比,在不破坏更改的情况下发展第二个选项要容易得多。如果您使用静态类型(Typescript、Flow、Scala.js、Reason 等),那么在前端使用接口会更有表现力并且肯定会更有趣。关键字:模式匹配。
上下文
我有一个 GraphQL API 和一个 NodeJS & Angular 应用程序,带有一个 MongoDB 数据库来保存用户。对于每个用户,都有一个 public 页面,其中包含 public 信息,例如 id
和 username
。用户登录后,会出现一个私人资料页面,其中包含 email
.
仅供参考,我正在使用 jsonwebtoken with accesscontrol 对用户进行身份验证和授权。该信息存储在每个 GraphQL 解析函数的上下文中,因此可以使用识别登录用户所需的任何信息。
我有一个 GraphQL 查询可以像这样检索 public 用户:
query getUserById($id: ID!) {
getUserById(id: $id) {
id,
username
}
}
我正在考虑检索 public 或私人用户的正确实现。由于 GraphQL 是强类型的,我在想出一个合适的解决方案时遇到了一些麻烦。
问题
如何区分public和私人用户?
注意事项
1.单独查询
因此,其中一种选择是对 public 和私有字段进行单独查询:
public查询
query getUserById($id: ID!) {
getUserById(id: $id) {
id,
username
}
}
私人查询
query getMe {
getMe {
id,
username,
email
}
}
2。使用 GraphQL 接口
我遇到了 this Medium article,它解释了 GraphQL 接口如何用于 return 基于 resolveType
函数的不同类型。所以我会这样做:
query getUser($id: ID!) {
getUser(id: $id) {
... on UserPrivate {
id,
username
}
... on UserPublic {
id,
username,
email
}
}
}
我还没有找到合适的解决方案,我不确定我目前的任何考虑。
非常感谢任何帮助!
我认为您在这里缺少的是,在 GraphQL 中,您通常想要创建这种深度连接的图形结构。虽然 getUserById
和 getMe
作为入口点工作得很好(而且我认为即使使用接口类型它们仍然是一个好主意),但您很可能会在整个架构中出现用户类型。想象一下热门博客post例子:
type Post {
id: ID!
title: String!
content: String!
author: User!
}
在这里添加两个作者字段并不是很好。同样,在您的示例中,您可能不知道个人资料页面是您自己的,直到您收到后端的响应(想想 Twitter 个人资料)。
相反,在我看来有两种方法可以考虑:
第一个是界面的想法。您将拥有一个接口,其中包含私有和 public 类型的所有公共字段和具体实现。这里的好处是:如果您只使用公共字段,您甚至不必使用类型匹配:
query getUser($id: ID!) {
getUser(id: $id) {
id
username
# if you need a private field you can branch off here
... on UserPrivate {
email
}
}
}
当它变得更细粒度时(人们分享他们想要公开给 public 的内容,想象一下 Facebook)或者你有很多类型(UserMe、UserFriend、UserStranger)你可能想要考虑 nullable字段代替。如果您无权访问该字段,您将从 API 收到空值。为了减少 null 检查的数量,您可以轻松地将字段捆绑到它们自己的类型中(例如 Address
)。
总结:
从 API 点开始,return 可为 null 的字段更容易一些,因为它为您提供了很大的灵活性。与第一个相比,在不破坏更改的情况下发展第二个选项要容易得多。如果您使用静态类型(Typescript、Flow、Scala.js、Reason 等),那么在前端使用接口会更有表现力并且肯定会更有趣。关键字:模式匹配。