Search code examples
restjson-patch

Removing multiple elements from an array using JSON patch


Say I have an entity that looks like this:

{
  "list": ["foo", "qux", "bar"]
}

If I want to remove "foo" and "bar" using one JSON patch with two operations. What is the correct syntax?

Option 1

This option expects the indexes to be immutable while the operations are being invoked.

[
  { "op": "remove", "path": "/list/0" }, // removes "foo"
  { "op": "remove", "path": "/list/2" }  // removes "bar" using original index
]

Option 2

This option expects the indexes to shift after the first operation has been invoked.

[
  { "op": "remove", "path": "/list/0" }, // removes "foo"
  { "op": "remove", "path": "/list/1" }  // removes "bar" using new index
]

Option 3

This option expects unexpected behavior could occur and guards itself.

[
  { "op": "remove", "path": "/list/2" }, // removes "bar" first to ignore shifting indexes
  { "op": "remove", "path": "/list/0" }  // removes "foo"
]

Option 3 is the safest option, I'm just mostly curious about what is correct. The RFC for JSON patch isn't clear on this.


Solution

  • The remove method on array members has implementation-dependent behaviour with relation to indexes, according the JSON Patch specification RFC 6902.

    As a result, all three of your suggestions are feasible and contingent on how they are implemented. It's important to note that option 1 implies the immutability of the indexes, which is not necessarily the case.

    Option 2 moves the indexes after the initial operation, which is a typical strategy and presupposes that the indexes are malleable. By eliminating the piece with the higher index first, Option 3 prevents problems with index shifting.

    It is advised to select option 3 or 2 if the order of the array's members is not crucial. The safest option is 3, as it prevents any potential index shifting problems. When the order of the remaining components is crucial and you're certain that the index shifting won't create any problems, you should select option 2, which is shorter.