Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graphql 突变方法是否需要处于顶层?_Graphql_Apollo_Apollo Server - Fatal编程技术网

Graphql 突变方法是否需要处于顶层?

Graphql 突变方法是否需要处于顶层?,graphql,apollo,apollo-server,Graphql,Apollo,Apollo Server,所有文档和教程通常都会显示如下简单的突变示例: extend type Mutation { edit(postId: String): String } type PostMutation { edit(postId: String): String } extend type Mutation { post: PostMutation } 但是,这样的edit方法必须在所有实体中都是唯一的,在我看来,这似乎不是一种非常健壮的编写东西的方法。我想用类似于我们描述查询的方式来描

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

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

extend type Mutation {
  post: PostMutation
}
但是,这样的
edit
方法必须在所有实体中都是唯一的,在我看来,这似乎不是一种非常健壮的编写东西的方法。我想用类似于我们描述查询的方式来描述突变,如下所示:

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

extend type Mutation {
  post: PostMutation
}
这似乎是一个有效的模式(它经过编译,我可以在生成的graph-I-ql文档中看到它的反映)。但是我找不到一种方法让解析器使用这个模式

这是GraphQL支持的情况吗?

这是可能的,但通常不是一个好主意,因为:

它违反了规范。来自:

由于顶级变异字段以外的字段的分辨率必须始终是无副作用且幂等的,因此执行顺序不得影响结果,因此服务器有权以其认为最佳的顺序执行字段条目

换句话说,只有突变根类型上的字段才会有CRUD操作之类的副作用

从概念上讲,在根节点上进行突变是有意义的。无论你在做什么操作(比如发帖、验证电子邮件、提交订单等),都不需要依赖GraphQL在执行操作之前解析其他字段。这与实际查询数据时不同。例如,要获取帖子的评论,我们可能需要解析每个帖子的
用户
字段,然后解析
帖子
字段,最后解析
评论
字段。在每个“级别”,字段的内容取决于父字段解析为的值。这通常不是突变的情况

在引擎盖下,突变按顺序解决。这与平行发生的正常场分辨率相反。这意味着,例如,
User
类型的
firstName
lastName
将同时解析。但是,如果您的操作类型为
突变
,则根字段将一次解析一个。在这样的查询中:

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

mutation SomeOperationName {
  user {
    create
    edit
    delete
  }
}
如果您仍然想这样做,尽管有上述情况,但在使用Apollo在引擎盖下使用的
makeExecutableSchema
时,您是这样做的:

const resolvers = {
  Mutation: {
    post: () => ({}), // return an empty object,
  },
  PostMutation: {
    edit: () => editPost(),
  },
  // Other types here
}
您的模式将
PostMutation
定义为对象类型,因此GraphQL希望该字段返回一个对象。如果省略
post
的解析程序,它将返回null,这意味着返回类型(
PostMutation
)的解析程序都不会被激发。也就是说,我们也可以写:

mutation {
  post
}

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

绝对不同意丹尼尔的观点

这是一种令人惊讶的方法,有助于前端用户快速了解一个或另一个资源/模型的运营情况。不要列出大量的突变列表

在一个请求中调用多个突变是常见的反模式。对于这种情况,最好创建一个复杂的突变

但即使您需要对多个突变执行此类操作,您也可以使用别名:

等待图形ql({
模式,
资料来源:`
突变{
op1:第{类(id:1)}条
op2:第{类(id:2)}条
op3:第{条不同于(id:3)}
op4:第{类(id:4)}条
}
`,
});
期望(连续结果)。toEqual([
“像超时100毫秒执行的1一样”,
'如2在超时100毫秒的情况下执行',
'与超时5ms执行的3不同',
“像4一样超时执行100毫秒”,
]);
请参见以下测试用例:


类似/不同的方法与超时不同步,并按顺序工作

,但基本上创建了相同的顶层突变。此外,你能解释一下为什么要使它强大吗?你有一个功能,将使一个职位。您认为如何再次使用它?这不是意见问题,而是规格问题。GraphQL规范专门将突变定义为顶级操作。下面的所有级别都是常规查询。事实上,它们实际上是在对事物进行变异,这是非常有问题的,因为查询和变异具有不同的执行语义和保证。这相当于公开一个GET端点,该端点在REST中向数据库写入内容。可能,但非常不安全,语义错误。