Subject: [apps-discuss] JSON Patch feedback

From: James M Snell <[email-masked]>
Date: Tue, 2 Oct 2012 09:36:13 -0700

Going through the current json-patch draft, I notice that it's particularly
light on examples and details for working with arrays. A few additional
array-specific examples in the text would be helpful... as well as a
reminder that array indexing with JSON Pointer is 0-based. (yes I know
there are a couple examples in the appendix but they're not quite enough)

In Section 4.1.. some of the language used is not quite clear... For
example:

   If the target location references the root of the target document or
   a member of an existing object, the specified location MUST already
   exist for the operation to be successful.

This would seem to imply that if I do...

  {"op": "add", "path": "/a/b/c", "value": 1}

That the path "/a/b/c" MUST already exist for the add to work, which is
contrary to the definition of "add". I suggest rewording section 4.1 to
something like the following (yes this is more verbose, but it's a lot
clearer and easier to understand than the existing text)

[START]
   The "add" operation adds a new value to a target location.  The
   operation object's "path" member identifies the position within an
   existing object or array to add the new value. The object MUST contain
   a "value" member that specifies the value to be added.

   For example, given the JSON document:

     {
       "a": {
         "b": {}
       }
     }

   A path of "/a/b/c" indicates that a new member "c" is being added to
   the object identified by "/a/b".

     {"op": "add", "path": "/a/b/c", "value": 1}

   Yields:

     {
       "a": {
         "b": {
           "c": 1
         }
       }
     }

   The add operation MUST fail if the object to which the member is being
added
   does not exist. Likewise, the add operation MUST fail if the target
object
   already contains a member with the same name. Using the same example
document
   given above:

     {"op": "add", "path": "/a/b", "value": "foo"}

   Would result in an error since "/a/b" refers to an existing member of
object "/a".

   If the value is being added to an array, the path will indicate the
specific
   position within the array to insert the item. For instance, given the
JSON
   document:

     {
       "a": {
         "b": [1,2,3]
       }
     }

   A path of "/a/b/1" would indicate that the new value is to be inserted
as the
   second item, causing any existing items at or above the specified
position to be
   shifted one position to the right.

     {"op": "add", "path": "/a/b/1", "value": 0}

   Yields:

     {
       "a": {
         "b": [1,0,2,3]
       }
     }

   The add operation MUST fail if the array to which the member is being
added
   does not exist. Note, however, that if the object referenced by the path
   "/a/b" points to an Object rather than an Array a new member named
   "1" will be added to that object.

   Specifying 0 (zero) as the index causes the value to be inserted at the
beginning
   of the array. Specifying an index equal to the current size of the array
causes
   the item to be appended as the last item in the array. The specified
index MUST be a
   non-negative integer and MUST NOT be greater than the number of items in
the array

     {"op": "add", "path": "/a/b/4", "value": 4}

   Yields:

     {
       "a": {
         "b": [1,0,2,3,4]
       }
     }

   While:

     {"op": "add", "path": "/a/b/10", "value": 'x'}
     {"op": "add", "path": "/a/b/-1", "value": 'y'}
     {"op": "add", "path": "/a/b/c",  "value": 'z'}

   Would each result in an error.

[END]

Lastly, it would be helpful to provide a few more Array examples in the
appendix... for instance:

Arrays nested within arrays. Given...

  {
    "a": [
      [1,2,3],
      ["A","B","C"]
    ]
  }

If I wished to swap the second elements of the two arrays, I would do...

  [
    {"op": "move", "path": "/a/0/1", "to": "/a/1/1"},
    {"op": "move", "path": "/a/1/2", "to": "/a/1/1"}
  ]

Which yields...

  {
    "a": [
      [1,"B",3],
      ["A",2,"C"]
    ]
  }

- James

---

From: "Manger, James H" <[email-masked]>
Date: Wed, 3 Oct 2012 12:49:55 +1000

>     {"op": "move", "path": "/a/1/2", "to": "/a/1/1"}

Not quite. The 2nd operation should be "to":"/a/0/1".