我在这里有些重复,但我试图找出我API API,以便一次性更新所有深度嵌套的记录。
这个例子是一个字典,其中的“术语”是这样的模式:
{
type: 'term',
id: uuid,
base: {
id: termId,
},
singular: true,
slug: 'create',
plural: true,
time: 'past, present, future',
continuous: true,
completed,
aspect: 'verb',
sense: 1,
images: [
],
gloss: {
text: 'gloss'
},
etymology: {
text: ''
},
origin: [
{
id: flowId,
}
],
derivations: [
],
translations: [
{
id: termId
}
],
pronunciations: [
{
name: 'ipa',
text: '',
}
],
definitions: [
{
text: '',
similarities: [
{
id: termId,
}
],
definitions: [
]
},
{
text: '',
source: {
id: citeId,
}
}
]
}
在最简单的情况下,我们通过API在嵌套树中创建每个对象,每次创建一个(假设我们处于“创建”阶段)。
POST /api/term { slug: 'foo' } => id == 123
POST /api/term/123/definition { text: 'hello' }
POST /api/term/123/definition { text: 'another' }
...
但这在几个方面似乎效率低下。但如果我们的UI表单在编辑每个输入后保存,则可能没有问题。实施起来可能有点棘手。
但更简单的方法是一次发送完整的JSON负载:
POST /api/term
{
slug: 'foo',
definitions: [
{ text: 'hello' },
{ text: 'another' },
]
}
这在这个“创建”的情况下工作得很好(与更新/删除相反),我只是在后端将其分解为单独的命令,就像我们之前所做的那样,但基本上是在DB级别。
但问题是如何做这种更“批处理”的方法,与更新和删除?看起来你真的不能以一种直截了当的方式做到这一点,这是对形势的正确阅读吗?
假设你已经创建了这个术语:
{
slug: 'foo',
definitions: [
{ text: 'hello' },
{ text: 'another' },
]
}
现在你想添加一个定义,你必须:
POST /api/term/:id/definition { text: 'a third' }
或者:
POST /api/term
{
definitions: [
{ id: 1 },
{ id: 2 },
{ text: 'a third' },
]
}
但接下来就开始变得棘手了,我们用{ id: 1 }
等是什么意思?我在想“保留我们刚刚通过ID传入的记录,并创建没有ID的记录”。但是如果你更复杂,说定义有一系列相关术语的“相似性”呢?
POST /api/term
{
definitions: [
{ id: 1, similarities: [ { id: 125 } ] },
{ id: 2 },
{ text: 'a third' },
]
}
现在我们编辑第一条记录,并创建最后一条记录。
现在假设我们要删除第二个。在UI表单中,我们删除第二个,添加与第一个的相似性,然后创建第三个。
POST /api/term
{
definitions: [
{ id: 1, similarities: [ { id: 125 } ] },
{ id: 2, _delete: true },
{ text: 'a third' },
]
}
是这样吗(借用我所记得的老Rails)。
总结/问题
总而言之,您可能有一个深度嵌套的记录,您可以在其中创建它的某些部分(嵌套记录),更新它的某些部分,并一次性删除它的某些部分。
从REST API或GraphQL API的Angular 来看,处理这种情况的标准方法是什么(基本上是将JSON发送到服务器的任何方法)?推荐的方法是什么,能够“批量”发送这些创建/更新/删除一次嵌套的JSON对象,并使其有效地写入PostgreSQL表?我不需要知道PostgreSQL的细节,只是说知道我的头在哪里。
自从我坐下来研究JSON API以来已经有一段时间了,所以现在已经有一段时间没有循环了,并且在我的记忆中没有处理这种情况的最佳方法。
其他注意事项
如果“字典术语”是一个很大的记录,比如有15个定义和很长的词源等等,那么每次更改一个条目时发送整个术语将是低效的。这就回到了第一个解决方案,即为每种记录类型设置API路由,并逐个调用它们。所以我有点困惑。
现在想想这样的事情:
{
type: 'term',
action: 'revision',
properties: {
definitions: [
{
action: 'revision',
filter: {
id: 123,
},
properties: {
text: {
action: 'overwrite',
value: 'bar',
}
}
},
{
action: 'deletion',
filter: {
id: 125
}
},
{
action: 'addition',
properties: {
text: 'foo'
}
},
]
}
}
1条答案
按热度按时间dkqlctbz1#
我最终这样做了,但更好的答案是受欢迎的!
查询
响应
摘要
它在很多方面都有点像GraphQL,你可以通过这种方式获取列表和列表的计数,使用
select
投影你想要的字段,并在选择查询的每个级别上进行过滤。然后使用effect
指定要写入的属性。对于插入查询,只允许嵌套插入。但是对于更新查询,您可以分散插入/更新/删除。