json-patch / json-patch2

A possibile revision to the JSON-Patch format
44 stars 0 forks source link

Indexed based array is too limited #12

Open jsumners opened 9 years ago

jsumners commented 9 years ago

Given the documents:

{
  "version": 0,
  "roles": [
    { "name": "foo", "value": "bar" },
    { "name": "baz", "value": "foobar" },
    { "name": "fjsl", "value": "dowfo" }
  ]
}

And:

{
  "version": 1,
  "roles": [
    { "name": "foo", "value": "bar" },
    { "name": "fjsl", "value": "dowfo" }
  ]
}

I want to be able to write a patch:

{ "op": "remove", "path": "/roles/name", "value": "foobar" }

This is useful when there is no guarantee that the array will always be in the same order, despite being guaranteed to have the same elements.

As JSON Patch currently works, I'm just going to re-factor my array into a hash. But it'd be nice to have this ability in the future.

grahamegrieve commented 8 years ago

+1 for this. This restriction makes JSON Patch simple to implement, but also restricts it to very simple cases. A more sophisticated JSON patch that allowed you to specify a selection criteria for remove and replace (particularly) would allow JSON Patch to be used for a more robust set of use cases, but would significantly increase the complexity. Also, to my knowledge, there's no candidate query for json with a standards track?

heruan commented 7 years ago

I agree, remove operation should permit to remove array elements without knowing the index. For example, given this JSON:

{
    "items": [ "a", "b", "c" ]
}

this patch should remove an item by value:

{ "op": "remove", "path": "/items/-", "value": "b" }

to result in:

{
    "items": [ "a", "c" ]
}

See #18.

konrad7d commented 7 years ago

+1. The ability to update or remove an element based on its property or wider selection criteria could be very useful.

aalquist-akamai commented 7 years ago

+1. this would make my logic more simple. For now, I'm using the test operator as a safety check.

HappyNomad commented 7 years ago

While navigating to the removal location, you may need to traverse more than one collection from which you need to select an element based on its property's value. The syntax proposed by @jsumners won't work in this more general case, since it splits the selection criteria into value of which there's only one.

Expressing each such traversal in the path as property=value is possible but unnecessarily complex. A simpler approach is to assume the identifying property's name and say that property's value where we'd otherwise say the element's index in the array. This involves eliminating array indices from the spec, or at least introducing an alternative "entity mode". Instead of array indices, we'd use the value of an element's "id" (not case-sensitive) property. For collections of scalar values, it would instead be the value itself.

So in @jsumners's simple example, the identifying property would be named "id" instead of "name". And the remove operation would be:

{ "op": "remove", "path": "/roles/foobar" }

@heruan Your proposal only addresses collections of scalar values. What about collections of complex types as in @jsumners's example?

mitar commented 4 years ago

As I wrote in this comment:

I feel this is going in the wrong direction and will make JSON patch be more and more like a programming language. I prefer to see JSON patch as a diff between known versions of JSON. Not a "program" to apply to unknown versions of JSON. The latter would then require more and more complicated logic. And how do we decide where it ends? Do you also want to define a function which computes the index at which to insert something? Or use regular expressions?