突变方法是否需要在顶层?

2024-01-19

所有文档和教程通常都会显示简单的突变示例,如下所示:

extend type Mutation {
  edit(postId: String): String
}

但这样一来edit方法在所有实体中必须是唯一的,对我来说这似乎不是一种非常可靠的编写方式。我想描述突变类似于我们描述查询的方式,如下所示:

type PostMutation {
  edit(postId: String): String
}

extend type Mutation {
  post: PostMutation
}

这似乎是一个有效的模式(它可以编译,我可以看到它反映在生成的 graph-i-ql 文档中)。但我找不到一种方法使解析器能够使用此架构。

这是 GraphQL 支持的案例吗?


It's possible但通常不是一个好主意,因为:

它打破了规范。 From 第6.3.1节 http://spec.graphql.org/June2018/#sec-Normal-and-Serial-Execution:

由于除顶级突变字段之外的字段的解析必须始终是无副作用和幂等的,因此执行顺序不得影响结果,因此服务器可以自由地以它认为最佳的任何顺序执行字段条目。

换句话说,只有突变根类型上的字段才应该有像 CRUD 操作这样的副作用。

从概念上讲,将突变放在根上是有意义的。无论您执行什么操作(点赞帖子、验证电子邮件、提交订单等),都不依赖于 GraphQL 在执行操作之前必须解析其他字段。这与您实际查询数据时不同。例如,要获得对帖子的评论,我们可能必须解决user场,然后是一个posts场,然后最后comments每个帖子的字段。在每个“级别”,字段的内容取决于父字段解析为的值。突变通常不会出现这种情况。

在幕后,突变是按顺序解决的。这与并行发生的正常场分辨率相反。这意味着,例如,firstName and lastName of a User类型同时解析。但是,如果您的操作类型是mutation,根字段将一次全部解析。所以在这样的查询中:

mutation SomeOperationName {
  createUser
  editUser
  deleteUser
}

每个突变都会按照它们在文档中出现的顺序一次发生一个。但是,这仅适用于根并且仅当操作是mutation,因此这三个字段将并行解析:

mutation SomeOperationName {
  user {
    create
    edit
    delete
  }
}

如果您仍然想这样做,尽管有上述情况,这就是您在使用时的做法makeExecutableSchema,这就是 Apollo 在底层使用的:

const resolvers = {
  Mutation: {
    post: () => ({}), // return an empty object,
  },
  PostMutation: {
    edit: () => editPost(),
  },
  // Other types here
}

您定义的架构PostMutation作为对象类型,因此 GraphQL 期望该字段返回一个对象。如果您省略解析器post,它将返回 null,这意味着没有返回类型的解析器(PostMutation)将被解雇。这也意味着,我们还可以写:

mutation {
  post
}

它什么也不做,但仍然是一个有效的查询。这是避免这种模式结构的另一个原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

突变方法是否需要在顶层? 的相关文章

随机推荐