json-patch / json-patch2

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

Increment / decrement #4

Open mnot opened 10 years ago

mnot commented 10 years ago

( from an e-mail from quentin.raynaud@lsystems.fr):

I'm currently working for TF1, a big television group in France. I'm working on a project that consist in rewriting all the base code that handles the data to expose it through an API. The idea is not to have any application use the database directly anymore but to use a single well thought API instead.

We quickly discovered we needed a good PATCH implementation to support the kind of performances and operations our software will need to manage.

I found out your proposed standard 6902 and was pretty pleased with everything except one tiny bit.

We have a lot of instances where we want to implement something like a vote system, where you want to increment a counter of a certain value without every time needing to know what the actual value is. To prevent read / lock / write / unlock on this kind of operations, we would very much like a way to say "add/substract x to the current value of attribute bar".

briancavalier commented 10 years ago

I see why some sort of atomic increment/decrement operation can be useful, but I also feel these operations are more like RPC calls than they are like patches. It also feels like a bit of a slippery slope. For instance, you could imagine wanting text transform operations (uppercase, lowercase, prepend, append, etc. etc.) or any number of other "blind" operations.

Perhaps it's possible to allow the op set to be extended with custom ops? IOW, JSON Patch defines the standard op set, but implementors may invent new ones if they want as long as they support the standard set. In fact, I don't think anything is really preventing that now--the rub is, of course, that the implementation you choose would need to support the desired operations, or provide the ability to plug-in new custom ops.

It opens up the big possibility of incompatibility between two parties exchanging patches, but I figured I'd throw it out there for discussion.

My personal feeling, at least right now, is that I'd rather see JSON Patch stick with a focused set of core operations, and make those operations as useful as possible.

nikmd23 commented 9 years ago

I have a similar requirement to quentin.raynaud@lsystems.fr. Mine is for a version property which I'd like to increment each time a patch is applied to a document.

That said, I agree with @briancavalier that any change in the spec to support this could quickly become a "bit of a slippery slope".

If something is done to support these changes, I'd prefer to see "dynamic values" rather than extensible op's. For example:

[
    { "op": "replace", "path": "/x/y/z", "value": "$++" }
]

In this case the $ in the value tells the patching implementation to increment the existing value. ($ chosen arbitrarily for this example. Any signaling character (set) would work.) This suggestion works well for numbers, but the other JSON types (string, object, array, bool, etc) would not be as easy to create adequate syntax for.

A more realistic implementation would leverage a strategy pattern with functions:

[
    { "op": "replace", "path": "/x/y/z", "value": "$increment" }
]

Where increment is the name of a function that the user has registered with the implementing library. The library will invoke said function and use the resultant value to apply to the document. I find this to be a bit cleaner that extensible op's.

Interoperability between parties would still be diminished with this approach. That risk could be mitigated by a set of predefined functions in the spec - but I realize that may open up a world of pain.

espadrine commented 7 years ago

For numbers in JSON, the ability to increment and decrement the value is much more useful than the ability to reset the value. Most numbers in JSON in the wild are either constant, or a value to be increased or decreased. Think of votes, counters, ledgers… Most protocols support increasing values (see for instance json0).

Having a mini-language or an extension seems weak for such a common use-case.

As far as other operations go, multiply might be useful for bitwise shifts but it seems too much of an edge-case, division is impossible (we can't allow a division by zero, since JSON doesn't have NaN). On the other hand, max and min are pretty useful, although it is still fairly rare.