json-ld / json-ld.org

JSON for Linked Data's documentation and playground site
https://json-ld.org/
Other
859 stars 152 forks source link

JSON-LD Patch #599

Open dlongley opened 6 years ago

dlongley commented 6 years ago

I'm just putting some ideas down here for how a JSON-LD patch system might be implemented. This may or may not turn into a spec we want to produce.

Suppose that we defined (loosely for now, can be more rigorous later) a JSON-LD patch like so:

{
  "@context": "https://w3id.org/jsonld-patch/v1",
  // the target object to be patched
  "target": "urn:some-uri-for-an-object",
  // a frame could be a URL to a frame or an embedded frame
  "frame": "urn:some-uri-for-a-frame-or-an-embedded-frame",
  // a JSON patch (https://tools.ietf.org/html/rfc6902)
  "patch": [{"op": "add", "path": "/foo", "value": "bar"}]
}

The processing rules for this would be:

  1. Dereference the target object.
  2. Apply the frame to the target object producing framed_output.
  3. Apply the JSON patch to framed_output producing patched_output.
  4. Optionally, apply a system-specific frame to patched_output to produce result.

For the optional final step, a system (aka application) may wish to allow clients to patch its documents but it will want to ensure that those documents maintain a certain shape and context. To do this, it could, as a final step, reframe the patched output using a system-specific frame that would include any context from patched_output with its own system-specific context appended to it. This would ensure that the system-specific shape and context had precedence over any changes by the client that incorporated new contextual information (i.e. any conflicts are resolved to the system-specific context).

This approach would allow developers to use JSON patch (which they are often familiar with) along with JSON-LD. For clients that only speak idiomatic JSON, the frame could be omitted and assumed to be some system default with some restraints on which fields they could add (i.e. only fields in the system default context).

Thoughts on this approach?

dlongley commented 6 years ago

There may need to be some additional processing rules if the frame includes any filtering -- or, at least, we'd have to specify what happens in that case with the output.

gkellogg commented 6 years ago

Have you considered simply doing patching in the RDF domain? the Linked Data Patch Format does a good job of this; I have an implementation here.

Having something more JSON friendly might be nice, but it could leverage the same patch semantics.

dlongley commented 6 years ago

@gkellogg,

Have you considered simply doing patching in the RDF domain?

Yes, I don't think Web developers will use it. We need a bridge technology.

cwebber commented 6 years ago

So I've been working on this over here. It really wasn't too much work... the main challenge was figuring out how to be sure that patches would work correctly against @sets and @graphs. For instance:

{"@context": "https://example.foo/some-context",
 "a-set": [
   {"someKey": "banana"},
   {"someKey": "apple"}]}

A json patch document might look like:

{op: 'add', path: '/a-set/2/anotherKey', value: 'grapefruit'}

But if a-set is unordered, there's no guarantee that patching the second object will patch the right thing when putting it in some store and pulling it out again, or framing it from RDF soup, etc. What can we do?

@dlongley and I discussed this and the best answer we could come up with was, if framing, to normalize the graph to quads or whatever, then restore from that and then frame, and then patch. The idea is that if jsonld.fromRDF preserves ordering of whatever triples it's handed are (and we have a specific ordering since we canonicalized it), and then jsonld.frame also preserves ordering, then we can be sure that we're patching the right object. Preliminary tests seems to indicate this works on a javascript-implementation level. A question is, does the specification algorithm actually ensure this is true? My next step is to read both the json-ld reading-from-RDF and framing algorithms and to make sure that they both do preserve ordering from their inputs. I'm going to look at it, but I have a feeling that @gkellogg already knows or can tell faster than I can. @gkellogg, what do you think?

It turns out there's a big advantage to jsonld-patch, one that I hadn't anticipated early on: if the above plan works, then this means that jsonld-patch can consistently patch documents with blank nodes which, to my knowledge, ld-patch cannot. That could be an interesting justification for the existence of this tooling, aside from contemporary developer familiarity.

gkellogg commented 6 years ago

JSON-LD algorithms do not preserve order, except for array values, but always require the keys to be ordered lexicographically. I don’t believe arrays of values are re=ordered. There may be some options to not order keys to achieve some performance improvement or remove repetitious ordering.

DiegoPino commented 6 years ago

@gkellogg about algorithms not preserving order v/s reordering. Does that also apply to https://json-ld.github.io/normalization/tests/index.html#manifest-urdna2015 ? does urdna2015 apply preordering/consistent ordering strategies to achieve "canonalization"?

dlongley commented 6 years ago

@gkellogg,

Gregg said (emphasis mine):

JSON-LD algorithms do not preserve order, except for array values

@cwebber, so long as canonicalization ensures a consistent order for the items that appear in those arrays then preserving array value order in JSON-LD algorithms is all we care about, right?

dlongley commented 6 years ago

@DiegoPino,

Does that also apply to https://json-ld.github.io/normalization/tests/index.html#manifest-urdna2015?

I suspect @gkellogg is not counting canonicalization as a "JSON-LD algorithm" -- because it isn't specific to JSON-LD.

does urdna2015 apply preordering/consistent ordering strategies to achieve "canonalization"?

Yes it does.

cwebber commented 6 years ago

JSON-LD algorithms do not preserve order, except for array values

@cwebber, so long as canonicalization ensures a consistent order for the items that appear in those arrays then preserving array value order in JSON-LD algorithms is all we care about, right?

Sounds like it to me. It sounds like this is a fairly incidental "feature" of json-ld's algorithms as specified in the API document, but one that could be key to jsonld-patch functioning. Which may mean we want to raise the priority of its preservation.