突变方法是否需要在顶层? [英] Are mutation methods required to be on the top level?

查看:21
本文介绍了突变方法是否需要在顶层?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

All docs and tutorials usually show simple examples of mutations that look like this:

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

但是这样 edit 方法必须在所有实体中都是唯一的,在我看来这不是一种非常健壮的编写方式.我想描述与我们描述查询类似的突变,如下所示:

But this way the edit method has to be unique across all entities, which to me seems like not a very robust way to write things. I would like to describe mutation similar to how we describe Queries, something like this:

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

extend type Mutation {
  post: PostMutation
}

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

This seems to be a valid schema (it compiles and I can see it reflected in the generated graph-i-ql docs). But I can't find a way to make resolvers work with this schema.

这是 GraphQL 支持的案例吗?

Is this a supported case for GraphQL?

推荐答案

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

It's possible but generally not a good idea because:

它违反了规范.来自 第 6.3.1 节:

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

Because the resolution of fields other than top‐level mutation fields must always be side effect‐free and idempotent, the execution order must not affect the result, and hence the server has the freedom to execute the field entries in whatever order it deems optimal.

换句话说,只有变异根类型上的字段才会有像 CRUD 操作那样的副作用.

In other words, only fields on the mutation root type should have side effects like CRUD operations.

在根上进行突变在概念上是有意义的.无论您在做什么(喜欢帖子、验证电子邮件、提交订单等)都不必依赖于 GraphQL在采取行动之前解析其他字段.这与您实际查询数据时不同.例如,要获取对帖子的评论,我们可能必须解析 user 字段,然后是 posts 字段,最后是 comments 字段对于每个帖子.在每个级别",字段的内容取决于父字段解析为的值.这通常不是突变的情况.

Having the mutations at the root makes sense conceptually. Whatever action you're doing (liking a post, verifying an email, submitting an order, etc.) doesn't rely on GraphQL having to resolve additional fields before the action is taken. This is unlike when you're actually querying data. For example, to get comments on a post, we may have to resolve a user field, then a posts field and then finally the comments field for each post. At each "level", the field's contents are dependent on the value the parent field resolved to. This normally is not the case with mutations.

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

Under the hood, mutations are resolved sequentially. This is contrary to normal field resolution which happens in parallel. That means, for example, the firstName and lastName of a User type are resolved at the same time. However, if your operation type is mutation, the root fields will all be resolved one at a time. So in a query like this:

mutation SomeOperationName {
  createUser
  editUser
  deleteUser
}

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

Each mutation will happen one at a time, in the order that they appear in the document. However, this only works for the root and only when the operation is a mutation, so these three fields will resolve in parallel:

mutation SomeOperationName {
  user {
    create
    edit
    delete
  }
}

如果你仍然想这样做,尽管上面做了,这就是你在使用 makeExecutableSchema 时的做法,这是 Apollo 在幕后使用的:

If you still want to do it, despite the above, this is how you do it when using makeExecutableSchema, which is what Apollo uses under the hood:

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

您的架构将 PostMutation 定义为对象类型,因此 GraphQL 期望该字段返回一个对象.如果省略 post 的解析器,它将返回 null,这意味着不会触发返回类型 (PostMutation) 的解析器.这也意味着,我们也可以这样写:

Your schema defined PostMutation as an object type, so GraphQL is expecting that field to return an object. If you omit the resolver for post, it will return null, which means none of the resolvers for the returning type (PostMutation) will be fired. That also means, we can also write:

mutation {
  post
}

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

which does nothing but is still a valid query. Which is yet another reason to avoid this sort of schema structure.

这篇关于突变方法是否需要在顶层?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆