代码之家  ›  专栏  ›  技术社区  ›  timetowonder

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

  •  2
  • timetowonder  · 技术社区  · 7 年前

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

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

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

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

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

    这是支持graphql的情况吗?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Daniel Rearden    7 年前

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

    这违反了惯例。 按照惯例,突变总是在根上。为了区分对不同类型进行相同操作,您可以命名您的突变,例如, editPost editComment 而不是仅仅 edit .

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

    在这种情况下,突变是按顺序解决的。 . 这与平行发生的法向场分辨率相反。例如,这意味着 firstName lastName A的 User 同时解析类型。但是,如果您的操作类型是 mutation ,根字段将一次解析一个。所以在这样的查询中:

    mutation SomeOperationName {
      createUser
      editUser
      deleteUser
    }
    

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

    mutation SomeOperationName {
      user {
        create
        edit
        delete
      }
    }
    

    如果您仍然想这样做,尽管有上述情况,这是您在使用 makeExecutableSchema 这就是阿波罗在引擎盖下使用的:

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

    您的架构已定义 PostMutation 作为对象类型,所以graphql希望该字段返回一个对象。如果你省略了分解器 post ,它将返回空值,这意味着返回类型没有解析程序。( 后突变 )将被解雇。也就是说,我们还可以写:

    mutation {
      post
    }
    

    它只做了一个有效的查询。这也是避免这种模式结构的另一个原因。

        2
  •  3
  •   nodkz    7 年前

    完全不同意丹尼尔!

    这是一种神奇的方法,有助于前台人员快速了解哪些操作具有一个或另一个资源/模型。也不要列出大量的突变。

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

    但是,即使您需要对几个突变进行这样的操作,您也可以使用别名:

    await graphql({
      schema,
      source: `
      mutation {
        op1: article { like(id: 1) }
        op2: article { like(id: 2) }
        op3: article { unlike(id: 3) }
        op4: article { like(id: 4) }
      }
    `,
    });
    
    expect(serialResults).toEqual([
      'like 1 executed with timeout 100ms',
      'like 2 executed with timeout 100ms',
      'unlike 3 executed with timeout 5ms',
      'like 4 executed with timeout 100ms',
    ]);
    

    请参见以下测试用例: https://github.com/nodkz/conf-talks/blob/master/articles/graphql/schema-design/ tests /mutations-test.js

    类似/不同的方法是具有超时的异步方法,并按顺序工作