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
}
它什么也不做,但仍然是一个有效的查询。这是避免这种模式结构的另一个原因。