Subject: [apps-discuss] Updated Merge Patch

From: James M Snell <[email-masked]>
Date: Thu, 18 Oct 2012 10:21:48 -0700

Based on received feedback, mostly editorial modifications and a few
updates to the rules to cover a couple additional cases (thanks to James
Manger for pointing out the gaps and providing new language for the intro).

  http://www.ietf.org/id/draft-snell-merge-patch-05.txt

- James

---

From: "Manger, James H" <[email-masked]>
Date: Fri, 19 Oct 2012 11:13:36 +1100

James,

draft-snell-merge-patch-05 looks better, but is not quite right.

§2 step 1
 If either the root of the JSON data provided in the payload or
 the root of the target resource are JSON Arrays, the target
 resource is to be replaced, in whole, by the provided data.
Implies (target + merge = result):
[1,2] + {"a":3, "b":null} = {"a":3, "b":null}
But the result should instead be {"a":3}.

The same mistake is made in step 2, 4th dot point.

Step 1 could be rewritten as:
  “If the root of the patch is a string, number, boolean, or array, the target is replaced with the patch value.”

This rule is not actually specific to the root so it probably doesn’t need to be a special case.

My stab at the processing rules:

“The processing steps walk through the object elements in the merge-patch document and the corresponding elements in the document being modified. Let ‘patch’ and ‘target’ represent the current position in these documents respectively. Initially ‘patch’ is the root of the merge-patch document, and ‘target’ is the root of the document being modified. At any point ‘target’ may not exist.

1.       If the patch value is null: remove target.
It is not an error if target does not exist, there is simply no modification to make.
Removing the root leaves an empty document (ie a resource with a content-length of 0).

2.       Otherwise, if the patch value is a string, number, boolean, or array: set target to patch. This creates a new object element if target didn’t exist, or replaces target’s value if it did exist.

3.       Otherwise, the patch value is an object. Perform the next two sub-steps:

a.       If target does not exist or if its value is not an object: set target to an element with the patch name, and an empty object as its value (ie {}).
For the root there isn’t really an element name, just a value.

b.      For each element of the patch value object: repeat the processing steps with patch being that element, and target being the element of the previous target with the same name (if such an element exists).
”

This is harder to write in English than code!

It would be worth including examples of the less obvious cases.

Target   + merge = result

{"a":[1,{"bb":2, "cc":3}]} + {"a":[1,{"bb":4, "cc":null}]} = {"a":[1,{"bb":4, "cc":null}]}
  (showing that you don’t merge objects within an array)

{"a":1} + {"b":{"cc":{"ddd":null}}} = {"a":1, "b":{"cc":{ }}}
  (showing that objects on a path get created (step 3a), even if the only tasks at the end of the path turns out to be removing elements)

[1,2] + {"a":3, "b":null} = {"a":3}
  (showing you still have to walk through the patch, even when the corresponding part of the target wasn’t also an object)

{"a":1} + null = <empty>

Splitting the processing steps and the worked example (section 2) into separate sections would be an improvement.

Then can we have this operation in json-patch: {"op":"merge", "path":<pointer>, "value":<merge-patch>}?

--
James Manger

From: [email-masked] [mailto:[email-masked]] On Behalf Of James M Snell
Sent: Friday, 19 October 2012 4:22 AM
To: IETF Apps Discuss
Subject: [apps-discuss] Updated Merge Patch

Based on received feedback, mostly editorial modifications and a few updates to the rules to cover a couple additional cases (thanks to James Manger for pointing out the gaps and providing new language for the intro).

- James

---

From: Jan Algermissen <[email-masked]>
Date: Fri, 19 Oct 2012 11:27:37 +0200

Hi James,

>   http://www.ietf.org/id/draft-snell-merge-patch-05.txt

Just thought that this bears an interesting use case for '+json'. Your media type does not only apply to application/json, but to all +json media types.

That said, a client can not only patch a resource with you media type that is available in application/json. It can also reasonably infer that if, if a resource is available as, eg. application/vnd.foo.product+json it makes sense to construct and send a PATCH using your media type.

That put a totally different light on +json, which I personally have seen as sort of YAGNI so far. Interesting.

You might want to consider making a note to that when you touch the draft next time.

Jan

> 
> - James
> _______________________________________________
> apps-discuss mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/apps-discuss

---

From: James M Snell <[email-masked]>
Date: Fri, 19 Oct 2012 09:12:42 -0700

+1 ... yes, that would be worthwhile to mention.

On Fri, Oct 19, 2012 at 2:27 AM, Jan Algermissen <[email-masked]
> wrote:

> Just thought that this bears an interesting use case for '+json'. Your
> media type does not only apply to application/json, but to all +json media
> types.
>
> That said, a client can not only patch a resource with you media type that
> is available in application/json. It can also reasonably infer that if, if
> a resource is available as, eg. application/vnd.foo.product+json it makes
> sense to construct and send a PATCH using your media type.
>