Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

We (Empirical) have implemented a similar couple years ago in our json-backed model. I see two big problems with this standard:

1. Why express paths as a string if you have the ability to encode it as an array in json? Otherwise you run up against the escaping problem for which they use ~0 and ~1 (of all things?!) which is only going to cause bugs.

2. Indexing into arrays is a problem in distributed computing because things can go out of sync super fast especially if these documents are concurrently shared across devices/users/caches. We solved this by making arrays into sets, whereby the sets are index by either a value (string, number) or in the case of containing more objects, having those objects specify a unique key (e.g. ["someArray", {"myUniqueKey": uniqueValue}, "propertyInsideTheObject"]. We maintain an ontology to know which keys are unique, but because we encode it in the patch itself the underlying platform doesn't need to know that hierarchy... it can simply look at each document's "myUniqueKey" to perform the update.

Thus our patches are always idempotent unlike the proposal.

If anyone is interested in any of this being open sourced (we have it production-quality in scala, java (android), objc, and javascript) let me know at aaron@empiric.al. It's a pretty powerful stack that we've considered open sourcing before... a bit like having your own version of Parse/Firebase but with a nicer/easier API.



Damn, thought I invented the array path thing :) I love how clear it is to read but my favorite thing is how easy it is to apply it:

  var x = { a: 1, b: 'B', c: { x: "X", y: "Y", z: "Z" }, d: [{p:"P"},{q:"Q"},{r:"R"}] };
  ["d", 1, "q"].reduce(function (prev, curr) { return prev[curr]; }, x);
  >>> "Q"
I got stuck at indexing as well. I feel like there's a good solution involving using an array element within the path array to denote a selector query of sorts but I haven't hashed it out yet.


If you're interested, this is the general structure and access method of the 'trie' data structure.

http://en.wikipedia.org/wiki/Trie

Also, Clojure has a nice functions called get-in and friends:

    user=> (def x {:a 1 :b 'B' :c { :x "X" :y "Y" :z "Z" } 
                   :d [{:p "P"} {:q "Q"} {:r "R"}] })
    #'user/x
    user=> (get-in x [:d 1 :q])
    "Q"
    user=> (assoc-in x [:d 1 :q] "QQ")
    {:a 1, :c {:z "Z", :y "Y", :x "X"}, :b B', :d [{:p "P"} {:q "QQ"} {:r "R"}]}


Isn't a path just a slash-delimited array?

To me, it's more readable as a path since we all deal with those everyday in our address bar. The machine can make it an array if it wants, but I'd prefer to see it in one line.

I do wish they'd gone with backslash as an escape character. Don't know what possessed them to pull ~0 and ~1 out of their butts.


The problem with backslash is that it's already used by the JSON parser. If you happened to have a key `\/`, that would need to be written "\\\\\\/".


That kind of inflation is just a side effect of format encapsulation. You're representing a path format inside the JSON format, both of which need to escape their delimiters if they're to be taken literally. I still think a single consistent escape character is cleanest.

The same argument applies when I have any defined escape character or delimiter that I want to use as a literal.

I'll admit it's less human readable if you have a key `\/` but I can't think of many good reasons you'd want that as a key, which is what makes them good escape characters and delimiters.


Seconded.

Paths as array is a much better way than escape codes. That would save people a lot of time in explaining and understanding, especially if this is going to be standardized.


We also faced this problem at work a while back, although, for XML.

My first iteration was similar in spirit to jsonpatch: a sequence of ops against the document. A XML patches grew things because mighty unwieldy and confusing. The maintainability of "diff operations" is incredibly low.

What I did in my second iteration was to have the patch document "look" like the document you are trying to create. Here's a document that will give you the general gist of how it worked (it's somewhat hard to describe in words): https://gist.github.com/jcdickinson/57e3a7e481a7e79f90b4

There are some operations (foreach, etc.) that I haven't included in the sample that are designed in an "operation" manner for scenarios where the structural approach won't work.

Either way it makes patches a lot more manageable and you may want to consider using it as inspiration. I included something rough in the gist to get the grey matter rolling.


While the escaping issues you mention are super nasty, those are from the JSON Pointer specification, which JSON Patch merely uses.


I emailed you, but also wanted to express in the comments that I would be definitely interested in idempotent json patches.


That's absolutely true about arrays but maintaining on ontology isn't a general-purpose solution for arbitrary JSON. Perhaps a simpler solution that applies patches to a known document in a specific order will still be useful in some cases?


> Why express paths as a string if you have the ability to encode it as an array in json?

Probably because it's mimicking XPath, which was the analogous string but for XML. Think regex as well, which is a string.


I love the idea of using an array. Sounds like arrest addition to the spec.


The paths are a standard


I'm pointing out flaws in the "standard."




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: