Reputation: 10624
Using the JSON Merge Patch specification, is there a way to identify members of a sub-collection in the target - for modification or deletion?
With the twist, that key
may be flagged as readOnly
!
For example, given the following original JSON document:
{
"a": "b",
"c": [
{
"key": "d",
"prop1": "e",
"prop2": "f"
},
{
"key": "g",
"prop": "h"
}
]
}
My gut (often wrong) tells me to send the following request:
PATCH /target HTTP/1.1
"c": [
{
"key": "d",
"prop1": "z"
},
]
To get the result:
{
"a": "b",
"c": [
{
"key": "d",
"prop1": "z",
"prop2": "f"
}
]
}
Does this, so far, make sense according to the spec?
But, what if key
is flagged as readOnly
in an OpenAPI schema? In that case we shouldn't technically be allowed to pass the key
(a UUID) on the wire.
Upvotes: 2
Views: 3834
Reputation: 18980
It looks like this is not how it works. I have tested your scenario using json-merge patch, an implementation of the JSON Merge Patch 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));
and this outputs:
{ "a": "b", "c": [{ "key": "d", "prop1": "z" } ] }
My explanation is, the patch value specified for c
is not an object but an array, and therefore the existing value is replaced entirely. When looking at RFC 7396 (which obsoletes RFC 7386) we find the application of a merge patch in pseudo-code:
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
My conclusion here is, an array has no name-value pair, and therefore does not enter the recursive processing but is simply returned, which means gets replaced by the patch value in your case.
Regarding the readOnly
flag, I strongly believe the merge patch operation is not schema-aware. The RFC does not mention anything in this respect.
Upvotes: 3