有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何通过JSON API实现复杂的条件批量部分更新?

HTTP协议中有用于部分更新的POSTPATCH方法。 在JSON API的PATCH方法上有RFC 5789RFC 6902RFC 7396

但我有一个问题是针对大型资源的,这些资源需要在相当复杂的条件下进行部分更新

假设我们有一个API endpont"/members",它类似于一个包含数千个条目的大型集合,其中每个条目都有几十个字段。因此,客户端通过带有分页的"GET /members?fields=f1,f2,f3"方法部分读取这些值,而每个客户端只读取对当前任务至关重要的字段子集

为了简化问题,我们假设任何条目都有一个用于标识的必需"email"字段和几个可选字段

{
"email": "user@organization.com",
"optional1": "x",
"optional2": "x",
"optional3": "x"
}

我们有两个客户并行工作,批量创建和更新新记录。但每个客户端只希望覆盖可选字段的子集

因此,客户机A将发送一个带有A值的请求,请求一个批量补丁,该补丁只允许覆盖"optional1"字段值,因为该字段对他们的任务至关重要。该客户机还将为新条目的"optional2"字段指定一个值。而且该客户机根本没有指定"optional3"字段

{
"email": "user@organization.com",
"optional1": "A",
"optional2": "A"
}

虽然该记录是新的,但它会完全写入存储器。 然后,客户机B将发送一个带有B值的请求,该请求将允许批量补丁覆盖"optional2"字段值,因为该字段对他们的任务至关重要

{
"email": "user@organization.com",
"optional1": "B",
"optional2": "B",
"optional3": "B"
}

由于该记录已经存在,该记录的"optional1"字段应保留相同的旧值A,因为该字段不是必需的,所以"optional2"字段值应被新值B覆盖,因为该字段是必需的,而"optional3"字段值应该接收值B,因为该字段只是空的。 行动的合并结果应如下所示

{
"email": "user@organization.com",
"optional1": "A",
"optional2": "B",
"optional3": "B"
}

因此,行为取决于记录的存在。 你们将如何在JSON API可重用端点方法中实现这一点,以便在复杂条件下对此类集合进行并行部分更新,从而允许该API的客户端仅覆盖记录中的字段子集(如果该记录已经存在并包含一些值)

RFC 6902解不匹配,因为它们的addreplace操作实际上都替换了一个值

add - If the target location specifies an object member that does exist, that member's value is replaced.

replace - The "replace" operation replaces the value at the target location with a new value. The operation object MUST contain a "value" member whose content specifies the replacement value.

您可以看到这与Java Map.put()方法是如何匹配的

If the map previously contained a mapping for the key, the old value is replaced by the specified value.

但是缺少的特性与Java Set.add()方法相匹配

Adds the specified element to this set if it is not already present (optional operation). More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

如何制作一个JSON API,允许对一个包含数十个可选字段的元素的大型集合的批量补丁进行这两种类型的操作


更新

感谢@chad jensen提出的属性优先级规则。 上述文件提供了非常灵活的方法,因此我试图根据自己的需要对其进行调整。我想我将有两个操作,一个是优先级较低的“初始化”,另一个是优先级较高的“添加”或“替换”

然后,在我的示例中,客户端A和客户端B发送的JSON数据如下所示

由客户端A发送的数据,它更新优先级较低的"optional2"字段,并更新优先级最高的"optional1"字段

{
    "email": "user@organization.com",
    "initialize":
    {
        "optional2": "A"
    },
    "replace":
    {
        "optional1": "A"
    }
}

由客户端B发送的数据,它更新优先级较低的"optional1""optional3"字段,并更新优先级最高的"optional2"字段

{
    "email": "user@organization.com",
    "initialize":
    {
        "optional1": "B",
        "optional3": "B"
    },
    "replace":
    {
        "optional2": "B"
    }
}

共 (1) 个答案

  1. # 1 楼答案

    您需要某种优先级映射来决定每个客户机的优先字段

    看起来你已经有了,但我将假设它存储在某个地方/服务器和/或客户端知道他们拥有最高优先级(优先级)的字段。您可能还需要知道哪个客户端上次更新了每个字段

    话虽如此,您应该能够对每个属性执行null/empty/检查,并且只在值为默认值(null/empty string)时替换它们。在值已经填充的情况下,则需要检查传入的客户端的优先级是否高于/低于上次更新值的客户端

    我找到了一个文档,它可能会澄清我的意思(它对某些第三方工具有点具体,但概念就在那里):https://www.ibm.com/support/knowledgecenter/en/SSPLFC_7.2.0/UserGuide/c_cmdb_reconcilation_overview.html