- From: Michael C. Thornburgh <zenomt@zenomt.com>
- Date: Sat, 30 Mar 2024 14:45:09 -0700 (PDT)
- To: public-linked-json@w3.org
i expected this to have come up already, but i didn't find this sentiment in list archives (including the CG and WG lists) or GitHub issues. i'm sure i'm not the only one to have thought this, though. in the interest of brevity (and foreshadowing), i'll leave most of this as bullets instead of prose. * the full JSON-LD spec is large and complex, and isn't really "lightweight" (anymore) * common implementations are huge (jsonld.js is 1.2 MB unminified, 287 KB minified, 84 KB min+gzip) * "developer friendly idiomatic JSON": - counterproductive for pure LD applications - coercions and other mappings mean a casual human reader can't actually be sure what the document is saying (as RDF) - need to know the JSON schema (formal or informal) of every document type one expects to encounter - assumes it's too hard, or too much code, to parse and work with RDF directly - relative URIs are desirable; those still need to be resolved * external contexts are problematic: - privacy - complexity - availability, especially when disconnected - temporal decoupling * i'd use Turtle for pure Linked Data applications, but processing Turtle is a lot of code and complexity too, unfortunately i propose a simplified profile of JSON-LD, inspired by Turtle: * @context can only define an @base, @vocab, and compact IRI prefixes * IRIs are always in an @id member (except for @type) * one graph per document (no @graph, use @included if needed) * no external contexts (documents are self-contained) * no recursive compact IRI prefix definitions * no coercions (except for @type itself) or other transformations * no @index, @reverse, @nest, @protected, @propogate, @import, etc. i'm calling this the "Terse" profile (since Turtle is the "Terse RDF Triple Language"), identified (for now) by profile URI http://zenomt.com/ns/jsonld-terse dereferencing that URI yields a more detailed and precise description of the constraints. my reference implementation for this profile is at https://github.com/zenomt/jsonld-terse it's currently 201 lines of plain JavaScript (about 7 KB, GitHub says "170 loc") with no external dependencies, and gzips to 2116 bytes. it parses and expands conforming documents to interconnected Plain Old JavaScript Objects, resolves relative URIs given the document's URI and any @base directives, and can render a graph as a JSON-LD tree rooted from any node (optionally relativizing URIs to a provided base, but not "compacting" with an @context) or as an array of triples. there's a test page included in the repo, and it's published to GitHub Pages so there's a live test page to play with. limitations of this implementation: @list is intentionally not expanded to an RDF List, since RDF Lists are harder to work with than JavaScript Arrays; only URIs are processed, since web browser JavaScript doesn't provide native IRI processing functions. IRIs in documents might end up transformed to URIs according to the JavaScript `URL` API. example Terse JSON-LD document: ``` { "@context": { "@base": "https://example.com/people/card", "foaf": "http://xmlns.com/foaf/0.1/", "schema": "http://schema.org/" }, "@id": "#me", "@type": ["foaf:Person", "schema:Person"], "foaf:name": { "@value": "Michael Thornburgh", "@language": "en-us" }, "foaf:nick": "Mike", "foaf:depiction": { "@id": "mike.jpg" }, "schema:worksFor": { "@type": "schema:Corporation", "schema:name": "Example Corp.", "schema:employee": { "@id": "#me" } }, "@included": [ { "@id": "", "@type": "foaf:PersonalProfileDocument", "foaf:primaryTopic": { "@id": "#me" } }, { "@id": "_:b86", "foaf:knows": { "@id": "_:b99" } }, { "@id": "_:b99", "foaf:knows": { "@id": "_:b86" } } ] } ``` equivalently expressed as idiomatic Turtle: ``` @base <https://example.com/people/card> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix schema: <http://schema.org/> . <#me> a foaf:Person, schema:Person; foaf:name "Michael Thornburgh"@en-us; foaf:nick "Mike"; foaf:depiction <mike.jpg>; schema:worksFor [ a schema:Corporation; schema:name "Example Corp."; schema:employee <#me> ] . <> a foaf:PersonalProfileDocument; foaf:primaryTopic <#me> . _:b86 foaf:knows _:b99 . _:b99 foaf:knows _:b86 . ``` i hope this is of interest and use to others. -michael thornburgh
Received on Sunday, 31 March 2024 10:18:08 UTC