登录不应该是GraphQL中的查询吗?

gas*_*ard 27 graphql

在GraphQL身份验证教程中,login是一个Mutation:

type Mutation {
  post(url: String!, description: String!): Link!
  signup(email: String!, password: String!, name: String!): AuthPayload
  login(email: String!, password: String!): AuthPayload
}
Run Code Online (Sandbox Code Playgroud)

登录不应该是查询,因为:

  1. 该操作对服务器没有副作用.
  2. 目标是查询令牌.

我在这里错过了什么吗?

Dan*_*den 61

在该示例的上下文中,login应该是Query而不是Mutation,因为它的解析器没有副作用,至少根据规范.但是,有几个原因你可能不会在野外看到这样做:

  • 如果您正在实施身份验证,则可能需要记录用户的帐户活动,方法是维护一些有关登录/注销事件的数据,或者至少在帐户记录中包含某种"上次登录"字段.修改该数据产生副作用.

  • 已经发展出一种惯例,即将用户操作产生的任何操作视为Mutations,而不考虑副作用.react-apollo例如,您可以看到这一点,其中Query组件在mount上触发关联查询,而Mutation组件只是公开可以调用以触发该查询的函数.如果您计划使用Apollo客户端,那么在设计架构时考虑这些客户端功能是值得的.

  • 突变是按顺序运行的,而查询是同时运行的.这意味着可以预见在同一个调用中触发登录变异和一个或多个其他突变,允许您利用经过身份验证的上下文进行后续调用.对于查询也是如此 - 如果login是查询,并且在同一操作中包含其他查询,则它们将同时开始解析.

除了它们的执行方式(顺序与同时)之外,在服务器端,查询和突变实际上是可以互换的.您可以查询副作用和突变,没有副作用.您可能应该坚持使用约定,但我认为有时候您可能需要将这些约定抛到窗外.

  • “突变是顺序运行的,而查询是同时运行的”,这是一个很好的观察。我完全不知道 谢谢。帮助您决定是将其解析为突变还是查询。 (5认同)
  • 注意 Apollo 现在有一个钩子“useLazyQuery”,在您手动触发加载之前它不会查询数据,与 useMutation 非常相似。但目前它不返回承诺(参见https://github.com/apollographql/react-apollo/issues/3499) (3认同)
  • 这个 x 100。如果“mutation”被称为(不可否认的是,不太吸引人的)“命令式、非缓存查询”,那么在这种情况下,它正是您想要的,那就更明显了。如果您喜欢辩论语义,我强烈建议您切换到 REST API,您可以在其中尽情享受。 (2认同)