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

2024-03-09

书面这个问题 https://stackoverflow.com/questions/52318135/defining-mutations-in-graphql-via-fields-is-this-bad-practice/52322818?noredirect=1#comment91605124_52322818我意识到我希望能够在 GraphQL 中做一些非常具体的事情,但我看不到实现它的好方法。这个想法是这样的:

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

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

这太棒了。通常,您想要收集数据意图改变它。因此,在这种情况下,也许我不想获取所有这些评论,而是想删除它们。一个天真的建议是实施deleteComment场上的comment类型,它会改变它所调用的对象。这是bad因为该请求被标记为query,所以它不应该改变数据。

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

现在,我认为“传统”的解决方案是创建一个突变字段来完成这项工作,而不是做其他事情。所以你定义了一个突变字段deleteAllUserPostCommentsByForum它需要一个参数,并以明显的方式实现它。但现在你已经失去了灵活性!如果您决定要找到user明确地删除他们的所有帖子,或者如果您只想删除some在他们的帖子中,您需要一个全新的突变字段。与 REST 相比,这正是我认为 GraphQL 有用的地方。

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


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

mutation myOperation {
  editComment(id: 1, body: "Hello!")
  deleteComment(id: 1)
}

The editComment突变将在之前解决deleteComment突变。如果这些操作是查询,那么它们将同时运行。同样,考虑一下是否有一个返回对象的突变,如下所示:

mutation myOperation {
  deleteComment(id: 1) {
    id
    name
  }
}

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

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

使突变更加灵活的关键在于如何将输入传递给突变,以及如何在解析器中处理这些输入。而不是制作一个deleteAllUserPostCommentsByForum突变,只需做一个deleteComments接受更稳健的输入类型的突变,例如:

input DeleteCommentsInput {
  forumId: ID
  userId: ID
}

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

实际上,您可以类似地处理创建和编辑,并让事情变得更干燥。例如,您的架构可能如下所示:

type Mutation {
  createOrUpdateComment(comment: CommentInput)
}

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GraphQL:你能改变查询的结果吗? 的相关文章

随机推荐

  • SIGABRT:前提条件失败:导入的节点在读取其值之前已被删除

    自从beta 5 of Xcode 11启动后 我不得不更新代码 你知道该怎么做 然而 有一个奇怪的运行时错误在更改中幸存下来 我无法弄清楚为什么会发生这种情况 我开始尝试将其限制在我的原始代码中 但令人惊讶的是 它也发生在我设法想出的最简
  • 单击时滚动到 div,最后循环

    我想做的是在屏幕右下角引入一个按钮 用户可以单击该按钮滚动到下一个 部分 div 一旦到达 html 中的最后一个 div 它应该循环回到第一个 divsection div 我提出的解决方案是 当页面最初加载时 它会收集类名称为 sect
  • Flask-SQLAlchemy ssl 连接与 AWS RDS 错误

    我正在尝试通过 ssl 将 Flask 应用程序 mysql 连接与 AWS RDS 连接 当我尝试像这样使用 mysql 客户端时它可以工作 mysql u user h myrds rds amazonaws com p ssl ca
  • Jquery - 从 div 读取所有类

    我试图通过以下方式从 HTML 元素读取所有类名 但它不起作用 HTML div class fff aaa ccc hello world div JS if test attr class Read classes var all cl
  • TIdNotify 和 TIdSync 有什么区别?

    我无法理解 IDSYNC 和 IDNOTIFY 之间的真正区别 同步 异步意味着什么 关于我写的代码行 procedure TForm1 IdTCPServerExecute AContext TIdContext begin DoSome
  • pthread_create函数中的第四个参数

    代码如下 int code pthread create d gt thread id attr QThreadPrivate start this which QThreadPrivate start是一个静态函数 那么 第四个参数有什么
  • 动态 Linq - String.Split

    Dynamic Linq 似乎没有实现 String Split 方法 有没有办法使用 Dynamic Linq 达到相同的结果 Dynamic Linq 确实支持 String Split 并且还调用其他 net 类型方法 如下所示 va
  • 如何连接回声[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我想知道如
  • 使用 useeffect 和 React Router 执行乱序

    我试图在我的 app js 中使用 useEffect 并将一些数据设置到我的 redux 中 并在我的路由页面 在 useEffect 内 中使用该数据 导致我发现这种奇怪的行为 除非它应该是这样 而且我在错误的 D 这是一个简化的代码来
  • 将绘图文本/二进制写入变量

    有没有办法有一个R设备 后记会很棒 将输出写入变量而不是文件 例如我知道这个 postscript file cat plot 1 10 dev off 将附言文本发送至STDOUT 我怎样才能将该文本放入其中的变量中R 我已经成功地将绘图
  • iOS4 睡眠时 Wifi 连接无法保持

    知道iOS4支持wifi在睡眠状态下保持存活真是一件令人高兴的事情 然而我得到了一些不同的经历 我有 2 台 iPod 第二代 iPod 和第三代 iPod 两者均更新至 iOS 4 beta iPod 2g 可以在睡眠时保持 WiFi 连
  • 安装时自动启动 Windows 服务

    我有一个使用 InstallUtil exe 安装的 Windows 服务 即使我已将启动方法设置为自动 但该服务在安装时并未启动 我必须手动打开服务并单击启动 有没有办法通过命令行或通过服务代码启动它 在 Installer 类中 添加
  • 如何将环境配置文件配置添加到 SBT

    在 Maven 中 您可以拥有 Profiles 它可以为不同的环境设置构建配置 例如 DEV QA UAT 生产 为了支持持续集成 必须有一种方法来告诉 SBT 在哪个环境上运行 如何在 SBT 中针对不同环境进行设置 例如 DEV QA
  • 使用 unnest 在 postgreSQL 中进行批量更新

    我正在尝试进行批量更新 gt update ti table set enabled T enabled from select from unnest array 2001622 2001624 2007903 as id unnest
  • 如何在本机反应中使用 MapLibre GL Js

    我正在寻找一种在我的反应本机应用程序中使用 OpenStreetMap 数据的方法 在我最近的研究中 我发现MapLibre https maplibre org 这是基于MapBox GL旧版本的免费选项 我面临的问题是 除了 react
  • 在线生成 JHipster 应用程序提供空白页面

    当我从本地安装的 JHipster 4 7 生成应用程序时 我可以通过运行 mvnw 在 localhost 8080 上启动它 没有任何问题 但是当我在线生成项目时https start jhipster tech https start
  • 如何用动画取消隐藏视图

    假设我在 iOS 版 Xcode 中有一个隐藏视图 现在 当我将视图设置为不隐藏 view hidden NO 时 如何使其现在显示 但带有动画 你可能想要的不是设置view hidden 但要设置view alpha to 0 对应于hi
  • sqlalchemy 连接到服务器,不指定数据库

    是否可以连接到MSSQL服务器 using sqlalchemy然后创建数据库 我使用以下内容 sqlalchemy create engine mssql pyodbc sa pwd localhost 但我收到一个错误 Detail D
  • XML:尾随部分不允许有内容

    我收到这些错误 Multiple annotations found at this line error Error parsing XML not well formed invalid token Content is not all
  • GraphQL:你能改变查询的结果吗?

    书面这个问题 https stackoverflow com questions 52318135 defining mutations in graphql via fields is this bad practice 52322818