gpt4 book ai didi

GraphQL:你能改变查询的结果吗?

转载 作者:行者123 更新时间:2023-12-01 12:57:39 27 4
gpt4 key购买 nike

书面通知 this question我意识到我想在 GraphQL 中做一些非常具体的事情,但我看不到实现它的好方法。这个想法是这样的:

GraphQL 的优点之一是它允许您进行灵活的查询。例如,如果我想找到所有 comments关于所有 posts每个user在特定 forum然后我可以进行查询

query{
findForum(id:7){
users{
posts{
comments{
content
}
}
}
}
}

这很棒。通常,您希望收集数据以对其进行变异。所以在这种情况下,也许我不想获取所有这些评论,而是想删除它们。一个天真的建议是实现 deleteComment场上 comment类型,它改变它被调用的对象。这是 因为请求被标记为 query ,所以它不应该改变数据。

由于我们正在改变数据,我们绝对应该将其标记为 mutation .但是随后我们就失去了进行我们想要查询的能力,因为 findForum是查询字段,而不是变异字段。解决此问题的一种方法可能是重新定义您需要在突变类型中的所有查询字段。这显然不是一个好主意,因为你重复了很多代码,而且还为 query做功能。 mutation 的严格子集.

现在,我认为“传统”的解决方案是制作一个突变字段,它可以完成这项工作,而不是别的。所以你定义了一个突变字段 deleteAllUserPostCommentsByForum这需要一个参数,并以明显的方式实现它。但现在你已经失去了灵活性!如果您决定要查找 user明确地,删除他们所有的帖子,或者如果你只想删除他们的一些帖子,你需要一个全新的变异字段。这感觉正是我认为 GraphQL 与 REST 相比有用的那种东西。

那么,有没有什么好的办法可以同时避免这些问题呢?

最佳答案

在幕后,查询和变更之间唯一真正的区别是,如果单个操作包含多个变更,它们将按顺序(一次一个)而不是并发解决。查询和所有其他字段同时解析。这意味着对于这样的操作:

mutation myOperation {
editComment(id: 1, body: "Hello!")
deleteComment(id: 1)
}
editComment突变将在 deleteComment 之前解决突变。如果这些操作是查询,它们将同时运行。同样,请考虑是否有一个返回对象的突变,如下所示:
mutation myOperation {
deleteComment(id: 1) {
id
name
}
}

在这种情况下, idname字段也同时解析(因为,即使它们作为突变的一部分返回,字段本身也不是突变)。

查询和突变之间的这种行为差异凸显了为什么按照惯例我们为每个操作定义一个突变,并避免像您的问题所暗示的那样“嵌套”突变。

使您的突变更加灵活的关键在于您如何将输入传递给您的突变,随后您如何在解析器中处理这些输入。而不是制作 deleteAllUserPostCommentsByForum突变,只需做一个 deleteComments接受更健壮的 InputType 的突变,例如:
input DeleteCommentsInput {
forumId: ID
userId: ID
}

然后您的解析器只需要处理可能传入的输入字段的任何组合。如果您使用的是 db,这种输入很容易转换为 WHERE条款。如果您意识到需要其他功能,例如在某个日期之前或之后删除评论,您可以将这些字段添加到您的输入类型并相应地修改您的解析器——无需创建新的变更。

您实际上可以类似地处理创建和编辑,并保持一些干燥。例如,您的架构可能如下所示:
type Mutation {
createOrUpdateComment(comment: CommentInput)
}

input CommentInput {
id: ID
userId: ID
body: String
}

然后,您的解析器可以检查是否包含 ID——如果包含,则将操作视为更新,否则将操作视为插入。当然,在这种情况下使用非空值可能会很棘手(创建而不是更新可能需要 userId),因此对于每种操作都有单独的输入类型有什么要说的。但是,希望这仍然说明了如何利用输入类型使您的突变更加灵活。

关于GraphQL:你能改变查询的结果吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52330018/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com