Graphql 中继突变:突变分页关联

Graphql 中继突变:突变分页关联,graphql,relayjs,Graphql,Relayjs,在很多情况下,我们会发生突变,其中存在一对多或多对多的关联,我们需要进行突变,并且该关联以分页列表的形式暴露于查询中 有几个关键要求: 客户端必须能够删除、添加和更新关联元素 在某些情况下,关联的顺序很重要,在这种情况下,客户机还必须能够对元素重新排序 不那么重要: 客户端应能够在创建父级时指定关联(例如,在创建产品的同时创建一组有序的变体) 客户机应该能够使用某种形式的事务原子性立即删除、添加、更新和重新排序关联元素 客户端不必为添加或删除单个元素而对整个当前关联进行分页 这个问题有很

在很多情况下,我们会发生突变,其中存在一对多或多对多的关联,我们需要进行突变,并且该关联以分页列表的形式暴露于查询中

有几个关键要求:

  • 客户端必须能够删除、添加和更新关联元素
  • 在某些情况下,关联的顺序很重要,在这种情况下,客户机还必须能够对元素重新排序
不那么重要:

  • 客户端应能够在创建父级时指定关联(例如,在创建产品的同时创建一组有序的变体)
  • 客户机应该能够使用某种形式的事务原子性立即删除、添加、更新和重新排序关联元素
  • 客户端不必为添加或删除单个元素而对整个当前关联进行分页
这个问题有很多可能的解决方案:

选项1-单一输入字段,无额外突变 输入类型有一个数组输入字段,它表示关联的全部真相(添加新元素,更新现有元素,删除缺少的元素,必要时保留顺序)

缺点:删除是非常含蓄的。客户端必须对关联的整个当前状态进行分页。不是颗粒状的

选项2-带位置的单个输入字段,删除 输入类型有一个数组输入字段,用于更新现有元素和添加新元素(忽略缺少的元素)。可以在元素上指定位置或索引值以对其重新排序。使用单独的突变来删除元素

缺点:当所有其他操作都在父代上时,在突变中自动关闭删除是不一致的。不是很颗粒

选项3-单个输入字段,删除和重新排序突变 输入类型有一个数组输入字段,用于更新现有元素和添加新元素(忽略缺少的元素)。单独的突变用于删除和重新排列元素

缺点:客户端无法将新元素添加到关联中的特定位置,必须添加新元素,然后单独重新排序。不是很颗粒

选项4-单个输入字段,添加/删除/重新排序 与选项3类似,但输入字段仅用于更新;一个单独的突变用于添加新元素

缺点:客户端必须进行多个突变才能执行复杂的更新。客户端无法创建具有初始关联的父级

选项5-完全分离的突变 父输入类型没有相关字段,所有操作都是通过添加/删除/更新/重新排序的四个单独的突变完成的

优点:非常明确和精细,使不同的数据模型对象保持分离。 缺点:客户端必须进行多个突变才能执行复杂的更新。客户端无法创建具有初始关联的父级

选项6-两个带位置的输入字段 输入类型有两个数组字段:一个用于更新、添加和重新排序元素(请参见选项2),另一个用于删除

缺点:感觉我们在污染母体突变;不是颗粒状的

选项7-两个输入字段,重新排序 与选项6类似,只是使用了一个单独的重新排序变异来代替位置参数

缺点:不一致的重新排序是关闭自己。另见选项6的缺点

所有这些选择似乎都有缺点。选项5似乎是最明确的,但要求用户同时使用多个突变,操作不再是真正的原子操作


Facebook是如何处理这些类型的突变的?你的方式是什么?谢谢

所有这些方法之间肯定存在权衡,因此选择一种方法实际上取决于我试图构建的内容

Facebook模式中最常见的情况有两个很好的限制:

  • 禁止重新订购
  • 无批量操作
Facebook上的评论就是典型的例子。对于这种情况,我们已经成功地使用了选项5,我可以自信地推荐它。作为评论,我们只有三个突变<代码>注释创建,
注释编辑
注释删除

对于这种情况,我们得出了共同的模式:

  • 对于
    创建
    编辑
    (或
    更新
    )突变,突变解析到的对象通常包含已修改的(其中我使用边的意义与我们在中使用边的意义相同)。从该边缘,您可以轻松地获得修改后的对象。。。但您也可以获得任何可能需要的边缘数据
  • delete
    通常只返回已删除对象的ID;如果客户机在输入中提供了该ID,那么这对客户机来说是一种纯粹的方便,但是如果删除输入获取了一些其他信息,并且服务器将其转换为ID,那么这将非常有用,在这种情况下,返回删除的ID允许客户机知道删除了哪个对象
选项5[…]客户端无法创建具有初始关联的父级

我不完全确定我是否遵循了这一点;我的评论示例中没有一个很好的例子(因为它不存在于产品中),但假设我想发布评论并同时回复该评论,我可以想象这样做:

commentCreate(输入:{text:“Hello World”,回复:[{text:“回复1”},{text:“回复2”}]})

其中,我正在重用
commentCreate
用作
回复所接受的复数输入类型的输入类型


对于需要重新排序或批量操作的情况,这听起来像是主要情况