Subject: [apps-discuss] JSON patch: setting a value; appending to an array

From: "Manger, James H" <[email-masked]>
Date: Sat, 22 Sep 2012 02:03:29 +1000

The current operations in draft-ietf-appsawg-json-patch-04 require the creator of a patch to know a fair bit about the current state of the JSON resource being patched — more than necessary.

Consider a JSON object that can have a element named "active". If you want the element to be "active":true the patch needs to be:
1.  [{"add":"/active", "value":true}]    if the "active" element is absent; or
2.  [{"replace":"/active", "value":true}]    if the "active" element is present.
Hence you cannot simply set the value with a patch without being sure of the old state.

As another example, consider appending to an array.
Old doc:  [2,3,5,7,11]
Patch:  {"add":"/5", "value":13}
New doc:  [2,3,5,7,11,13]
You need to know the current length of the array (5) to append a value. [You can insert a new item at the start of the array without knowing the array length, but that is less common.]

It would be useful to be able to construct patches for the two tasks above without knowing the current resource state. That could save a round trip and/or avoid some synchronization requirements. The "test" operation can be used when it’s necessary to ensure a JSON doc is in the correct state to apply a patch.

I suggest we define an new operation: "join".
It takes two parameters: a pointer; and a value.

When the value is an array the pointer must also identify an array (otherwise it is an error). The items from the value array are appended to the identified array in order.

When the value is an object the pointer must also identity an object (otherwise it is an error). The elements in the value are added to the identified object, replacing any elements with the same keys.

It is an error if the value is not an array or an object.
[though "join"ing two numbers could be defined as numerical addition: useful or too cute?]

Example:
Old doc: {"obj":{"a":"foo", "b":"bar"}, "job":[2,3,5,7,11]}

Patches: [
  {"join":"/obj", "value":{"b":"BAR", "c":"BAZ"}},
  {"join":"/job", "value":[13]}
]

New doc:  {"obj":{"a":"foo", "b":"BAR", "c":"BAZ"}, "job":[2,3,5,7,11,13]}

--
James Manger