使用 JSON Merge Patch,如何引用子集合的成员?

Using JSON Merge Patch, how do I reference members of sub-collection?

使用 JSON Merge Patch 规范,有没有办法识别目标中子集合的成员 - 进行修改或删除?

经过扭曲,key 可能会被标记为 readOnly!

例如,给定以下原始 JSON 文档:

{
  "a": "b",
  "c": [
    {
      "key": "d",
      "prop1": "e",
      "prop2": "f"
    },
    {
      "key": "g",
      "prop": "h"
    }
  ]
}

我的直觉(经常出错)告诉我发送以下请求:

PATCH /target HTTP/1.1
  "c": [
    {
      "key": "d",
      "prop1": "z"
    },
  ]

得到结果:

{
  "a": "b",
  "c": [
    {
      "key": "d",
      "prop1": "z",
      "prop2": "f"
    }
  ]
}

到目前为止,根据规范,这是否有意义?

但是,如果 key 在 OpenAPI 架构中被标记为 readOnly 怎么办?在那种情况下,技术上我们不应该被允许在线传递 key(一个 UUID)。

看起来这不是它的工作原理。我已经使用 json-merge patch 测试了您的方案,JSON 合并补丁 RFC 7396 的实现,

var jsonmergepatch = require('json-merge-patch');    
var source = {
  "a": "b",
  "c": [
    {
      "key": "d",
      "prop1": "e",
      "prop2": "f"
    },
    {
      "key": "g",
      "prop": "h"
    }
  ]
};    
var patch = {
  "c": [
    {
      "key": "d",
      "prop1": "z"
    },
  ]
};
var target = jsonmergepatch.apply(source, patch);
console.log(JSON.stringify(target));

这输出:

{
    "a": "b",
    "c": [{
            "key": "d",
            "prop1": "z"
        }
    ]
}

我的解释是,为c指定的补丁值不是对象而是数组,因此现有值将被完全替换。在查看 RFC 7396(废弃 RFC 7386)时,我们发现伪代码中合并补丁的应用:

define MergePatch(Target, Patch):
 if Patch is an Object:
   if Target is not an Object:
     Target = {} # Ignore the contents and set it to an empty Object
   for each Name/Value pair in Patch:
     if Value is null:
       if Name exists in Target:
         remove the Name/Value pair from Target
     else:
       Target[Name] = MergePatch(Target[Name], Value)
   return Target
 else:
   return Patch

这里我的结论是,数组没有名值对,因此不会进入递归处理,只是简单的返回,也就是在你的情况下被补丁值替换。

关于 readOnly 标志,我坚信合并补丁操作不是模式感知的。 RFC 在这方面没有提及任何内容。