【问题标题】:What is the meaning of viewer field in GraphQL?GraphQL 中查看器字段的含义是什么?
【发布时间】:2016-10-04 18:09:41
【问题描述】:

GraphQL 中根查询字段viewer 的作用是什么?

基于this articleviewer 可用于接受令牌参数,以便我们查看当前登录的用户。

我应该如何实现它?

【问题讨论】:

  • Relay Modern 中不再需要查看器模式
  • 奇怪的是我找不到任何具体的例子(使用 SQL 或 Mongo),只是对这个主题进行了很多抽象。希望有一个真实的例子,只是想看看实现。
  • 我不再推荐 Viewer 模式,它是 Relay Classic 的东西,你应该使用 me: UserType 字段而不是检查 Relay Workshop 以获得更好的示例 github.com/sibelius/relay-workshop/blob/master/packages/server/…

标签: graphql relayjs


【解决方案1】:

viewer 字段(设计模式)背后的想法是对仅与当前登录用户相关的顶级查询字段进行分组。例如:

# EXAMPLE 1

quer {
  viewer {
    stories { ... } # the list of published stores as well as drafts (current user)
  }

  stories { ... }   # the list of published stories (all users)
}

此当前记录的用户数据要么合并到 viewer 字段本身,要么嵌套在它下面:

# EXAMPLE 2

query {
  viewer {
    id
    email
    displayName
    stories { ... }
  }
}

# EXAMPLE 3

query {
  viewer {
    me { id email displayName }
    stories { ... }
  }
}

上述所有三个示例都可以通过完全删除 viewer 字段来简化,并且仍然具有完全相同的功能(推荐):

query {
  # The currently logged in user or NULL if not logged in
  me {
    id
    email
    displayName
  }

  # Published stories only (all users)
  stories {
    ...
  }

  # Published stories as well as drafts (the current user)
  stories(drafts: true) {
    ...
  }
}

您可以在GraphQL API and Relay Starter Kit 中找到完整的示例,它可以用作参考项目或新开发的种子/模板。见api/graphql.ts

【讨论】:

  • 为什么您(或谁)建议不要使用查看器,而是使用独立查询? (还在学习中)
  • 因为它更简单、更干净;引入“查看器”字段听起来像是在尝试解决一些假设的(不存在的)问题。
  • 我不同意这个建议。经过身份验证的用户和任何其他普通用户有非常不同的关注点和需要解决的不同问题,特别是哪些字段应该可见。您应该无法查询平台上任何用户的SSN,但您应该可以查询自己登录的SSN。
  • @Deal 对单个字段的权限在实体 GraphQL 类型内部强制执行(它与“查看器”顶级字段无关)。这是一个例子:github.com/kriasoft/nodejs-api-starter/blob/main/api/types/…
  • 我仍然不同意@KonstantinTarkus。您的示例是微不足道的,随着时间的推移,您对用户的定义变得混乱。现在假设您需要引入“团队成员”的概念,他们在技术上是用户,如果您在同一个团队中,您应该能够查询他们的电子邮件地址。您的解析器将使用大量 if 语句来试图确定用户是否可以查看它。真正的解决方案是用户界面,以及实现该界面的对象:查看器、团队成员等。
【解决方案2】:

viewer根查询字段的用途

viewer 不是 GraphQL 或 Relay 特定的东西。大多数 Web 应用程序服务于其用户或查看者的某些目的。对提供给用户的各种数据进行建模的顶级实体可以命名为viewer。您也可以将其命名为user。例如,Relay todo example 有一个 viewer 根查询字段:

viewer: {
  type: GraphQLUser,
  resolve: () => getViewer(),
},

我们也可以不用viewer。例如,Relay starwars example 没有任何 viewer 根查询字段。

简而言之,将这个viewer 作为 GraphQL 模式的根查询字段使我们能够提供基于当前用户的数据。

实现:如何与查看器一起使用身份验证令牌

我的回答遵循您提到的文章中已经描述的内容。步骤是:

  1. 在服务器端,创建突变以获取身份验证令牌。让我们将其命名为LoginMutation。此突变的输入是用户凭据,输出是身份验证令牌。

  2. 在客户端,如果您使用relay framework,请实现客户端突变。变异成功后,存储认证令牌。

  3. 在客户端中继代码上,为您的viewer 查询添加authToken 参数。 authToken 的值是登录突变成功后收到的认证令牌。

另一种选择

正如文章中已经提到的,验证用户的另一种方法是在 GraphQL 之外进行。您可能希望看到两个出色的答案 thisthis 了解详情。

Jonas Helfer 写了一篇由两部分组成的文章,您会发现它非常有用:Part 1Part 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2016-08-14
    • 2019-04-27
    • 2010-10-22
    • 1970-01-01
    • 2011-03-10
    • 2019-05-06
    相关资源
    最近更新 更多