1 | jsonld.js
|
2 | =========
|
3 |
|
4 | [![Build status](https://img.shields.io/github/workflow/status/digitalbazaar/jsonld.js/Node.js%20CI)](https://github.com/digitalbazaar/jsonld.js/actions?query=workflow%3A%22Node.js+CI%22)
|
5 | [![Coverage status](https://img.shields.io/codecov/c/github/digitalbazaar/jsonld.js)](https://codecov.io/gh/digitalbazaar/jsonld.js)
|
6 | [![Dependency Status](https://img.shields.io/david/digitalbazaar/jsonld.js.svg)](https://david-dm.org/digitalbazaar/jsonld.js)
|
7 |
|
8 | Introduction
|
9 | ------------
|
10 |
|
11 | This library is an implementation of the [JSON-LD][] specification in
|
12 | JavaScript.
|
13 |
|
14 | JSON, as specified in [RFC7159][], is a simple language for representing
|
15 | objects on the Web. Linked Data is a way of describing content across
|
16 | different documents or Web sites. Web resources are described using
|
17 | IRIs, and typically are dereferencable entities that may be used to find
|
18 | more information, creating a "Web of Knowledge". [JSON-LD][] is intended
|
19 | to be a simple publishing method for expressing not only Linked Data in
|
20 | JSON, but for adding semantics to existing JSON.
|
21 |
|
22 | JSON-LD is designed as a light-weight syntax that can be used to express
|
23 | Linked Data. It is primarily intended to be a way to express Linked Data
|
24 | in JavaScript and other Web-based programming environments. It is also
|
25 | useful when building interoperable Web Services and when storing Linked
|
26 | Data in JSON-based document storage engines. It is practical and
|
27 | designed to be as simple as possible, utilizing the large number of JSON
|
28 | parsers and existing code that is in use today. It is designed to be
|
29 | able to express key-value pairs, RDF data, [RDFa][] data,
|
30 | [Microformats][] data, and [Microdata][]. That is, it supports every
|
31 | major Web-based structured data model in use today.
|
32 |
|
33 | The syntax does not require many applications to change their JSON, but
|
34 | easily add meaning by adding context in a way that is either in-band or
|
35 | out-of-band. The syntax is designed to not disturb already deployed
|
36 | systems running on JSON, but provide a smooth migration path from JSON
|
37 | to JSON with added semantics. Finally, the format is intended to be fast
|
38 | to parse, fast to generate, stream-based and document-based processing
|
39 | compatible, and require a very small memory footprint in order to operate.
|
40 |
|
41 | Conformance
|
42 | -----------
|
43 |
|
44 | This library aims to conform with the following:
|
45 |
|
46 | * [JSON-LD 1.0][],
|
47 | W3C Recommendation,
|
48 | 2014-01-16, and any [errata][]
|
49 | * [JSON-LD 1.0 Processing Algorithms and API][JSON-LD 1.0 API],
|
50 | W3C Recommendation,
|
51 | 2014-01-16, and any [errata][]
|
52 | * [JSON-LD 1.0 Framing][JSON-LD 1.0 Framing],
|
53 | Unofficial Draft,
|
54 | 2012-08-30
|
55 | * [JSON-LD 1.1][JSON-LD CG 1.1],
|
56 | Draft Community Group Report,
|
57 | 2018-06-07 or [newer][JSON-LD CG latest]
|
58 | * [JSON-LD 1.1 Processing Algorithms and API][JSON-LD CG 1.1 API],
|
59 | Draft Community Group Report,
|
60 | 2018-06-07 or [newer][JSON-LD CG API latest]
|
61 | * [JSON-LD 1.1 Framing][JSON-LD CG 1.1 Framing],
|
62 | Draft Community Group Report,
|
63 | 2018-06-07 or [newer][JSON-LD CG Framing latest]
|
64 | * Community Group [test suite][]
|
65 |
|
66 | The [JSON-LD Working Group][JSON-LD WG] is now developing JSON-LD 1.1. Library
|
67 | updates to conform with newer specifications will happen as features stabilize
|
68 | and development time and resources permit.
|
69 |
|
70 | * [JSON-LD 1.1][JSON-LD WG 1.1],
|
71 | W3C Working Draft,
|
72 | 2018-12-14 or [newer][JSON-LD WG latest]
|
73 | * [JSON-LD 1.1 Processing Algorithms and API][JSON-LD WG 1.1 API],
|
74 | W3C Working Draft,
|
75 | 2018-12-14 or [newer][JSON-LD WG API latest]
|
76 | * [JSON-LD 1.1 Framing][JSON-LD WG 1.1 Framing],
|
77 | W3C Working Draft,
|
78 | 2018-12-14 or [newer][JSON-LD WG Framing latest]
|
79 | * Working Group [test suite][WG test suite]
|
80 |
|
81 | The [test runner][] is often updated to note or skip newer tests that are not
|
82 | yet supported.
|
83 |
|
84 | Installation
|
85 | ------------
|
86 |
|
87 | ### Node.js + npm
|
88 |
|
89 | ```
|
90 | npm install jsonld
|
91 | ```
|
92 |
|
93 | ```js
|
94 | const jsonld = require('jsonld');
|
95 | ```
|
96 |
|
97 | ### Browser (bundler) + npm
|
98 |
|
99 | ```
|
100 | npm install jsonld
|
101 | ```
|
102 |
|
103 | Use your favorite bundling technology ([webpack][], [Rollup][], etc) to
|
104 | directly bundle your code that loads `jsonld`. Note that you will need support
|
105 | for ES2017+ code.
|
106 |
|
107 | ### Browser Bundles
|
108 |
|
109 | The built npm package includes bundled code suitable for use in browsers. Two
|
110 | versions are provided:
|
111 |
|
112 | - `./dist/jsonld.min.js`: A version built for wide compatibility with modern
|
113 | and older browsers. Includes many polyfills and code transformations and is
|
114 | larger and less efficient.
|
115 | - `./dist/jsonld.esm.min.js`: A version built for features available in
|
116 | browsers that support ES Modules. Fewer polyfills and transformations are
|
117 | required making the code smaller and more efficient.
|
118 |
|
119 | The two bundles can be used at the same to to allow modern browsers to use
|
120 | newer code. Lookup using `script` tags with `type="module"` and `nomodule`.
|
121 |
|
122 | Also see the `webpack.config.js` if you would like to make a custom bundle for
|
123 | specific targets.
|
124 |
|
125 | #### Browser (AMD) + npm
|
126 |
|
127 | ```
|
128 | npm install jsonld
|
129 | ```
|
130 |
|
131 | Use your favorite technology to load `node_modules/dist/jsonld.min.js`.
|
132 |
|
133 | #### CDNJS CDN
|
134 |
|
135 | To use [CDNJS](https://cdnjs.com/) include this script tag:
|
136 |
|
137 | ```html
|
138 | <script src="https://cdnjs.cloudflare.com/ajax/libs/jsonld/1.0.0/jsonld.min.js"></script>
|
139 | ```
|
140 |
|
141 | Check https://cdnjs.com/libraries/jsonld for the latest available version.
|
142 |
|
143 | #### jsDeliver CDN
|
144 |
|
145 | To use [jsDeliver](https://www.jsdelivr.com/) include this script tag:
|
146 |
|
147 | ```html
|
148 | <script src="https://cdn.jsdelivr.net/npm/jsonld@1.0.0/dist/jsonld.min.js"></script>
|
149 | ```
|
150 |
|
151 | See https://www.jsdelivr.com/package/npm/jsonld for the latest available version.
|
152 |
|
153 | #### unpkg CDN
|
154 |
|
155 | To use [unpkg](https://unpkg.com/) include this script tag:
|
156 |
|
157 | ```html
|
158 |
|
159 | <script src="https://unpkg.com/jsonld@1.0.0/dist/jsonld.min.js"></script>
|
160 | ```
|
161 |
|
162 | See https://unpkg.com/jsonld/ for the latest available version.
|
163 |
|
164 | ### JSPM
|
165 |
|
166 | ```
|
167 | jspm install npm:jsonld
|
168 | ```
|
169 |
|
170 | ``` js
|
171 | import * as jsonld from 'jsonld';
|
172 | // or
|
173 | import {promises} from 'jsonld';
|
174 | // or
|
175 | import {JsonLdProcessor} from 'jsonld';
|
176 | ```
|
177 |
|
178 | ### Node.js native canonize bindings
|
179 |
|
180 | For specialized use cases there is an optional [rdf-canonize-native][] package
|
181 | available which provides a native implementation for `canonize()`. It is used
|
182 | by installing the package and setting the `useNative` option of `canonize()` to
|
183 | `true`. Before using this mode it is **highly recommended** to run benchmarks
|
184 | since the JavaScript implementation is often faster and the bindings add
|
185 | toolchain complexity.
|
186 |
|
187 | ```
|
188 | npm install jsonld
|
189 | npm install rdf-canonize-native
|
190 | ```
|
191 |
|
192 | Examples
|
193 | --------
|
194 |
|
195 | Example data and context used throughout examples below:
|
196 | ```js
|
197 | const doc = {
|
198 | "http://schema.org/name": "Manu Sporny",
|
199 | "http://schema.org/url": {"@id": "http://manu.sporny.org/"},
|
200 | "http://schema.org/image": {"@id": "http://manu.sporny.org/images/manu.png"}
|
201 | };
|
202 | const context = {
|
203 | "name": "http://schema.org/name",
|
204 | "homepage": {"@id": "http://schema.org/url", "@type": "@id"},
|
205 | "image": {"@id": "http://schema.org/image", "@type": "@id"}
|
206 | };
|
207 | ```
|
208 |
|
209 | ### [compact](http://json-ld.org/spec/latest/json-ld/#compacted-document-form)
|
210 |
|
211 | ```js
|
212 | // compact a document according to a particular context
|
213 | const compacted = await jsonld.compact(doc, context);
|
214 | console.log(JSON.stringify(compacted, null, 2));
|
215 | /* Output:
|
216 | {
|
217 | "@context": {...},
|
218 | "name": "Manu Sporny",
|
219 | "homepage": "http://manu.sporny.org/",
|
220 | "image": "http://manu.sporny.org/images/manu.png"
|
221 | }
|
222 | */
|
223 |
|
224 | // compact using URLs
|
225 | const compacted = await jsonld.compact(
|
226 | 'http://example.org/doc', 'http://example.org/context', ...);
|
227 | ```
|
228 |
|
229 | ### [expand](http://json-ld.org/spec/latest/json-ld/#expanded-document-form)
|
230 |
|
231 | ```js
|
232 | // expand a document, removing its context
|
233 | const expanded = await jsonld.expand(compacted);
|
234 | /* Output:
|
235 | {
|
236 | "http://schema.org/name": [{"@value": "Manu Sporny"}],
|
237 | "http://schema.org/url": [{"@id": "http://manu.sporny.org/"}],
|
238 | "http://schema.org/image": [{"@id": "http://manu.sporny.org/images/manu.png"}]
|
239 | }
|
240 | */
|
241 |
|
242 | // expand using URLs
|
243 | const expanded = await jsonld.expand('http://example.org/doc', ...);
|
244 | ```
|
245 |
|
246 | ### [flatten](http://json-ld.org/spec/latest/json-ld/#flattened-document-form)
|
247 |
|
248 | ```js
|
249 | // flatten a document
|
250 | const flattened = await jsonld.flatten(doc);
|
251 | // output has all deep-level trees flattened to the top-level
|
252 | ```
|
253 |
|
254 | ### [frame](http://json-ld.org/spec/latest/json-ld-framing/#introduction)
|
255 |
|
256 | ```js
|
257 | // frame a document
|
258 | const framed = await jsonld.frame(doc, frame);
|
259 | // output transformed into a particular tree structure per the given frame
|
260 | ```
|
261 |
|
262 | ### <a name="canonize"></a>[canonize](http://json-ld.github.io/normalization/spec/) (normalize)
|
263 |
|
264 | ```js
|
265 | // canonize (normalize) a document using the RDF Dataset Normalization Algorithm
|
266 | // (URDNA2015), see:
|
267 | const canonized = await jsonld.canonize(doc, {
|
268 | algorithm: 'URDNA2015',
|
269 | format: 'application/n-quads'
|
270 | });
|
271 | // canonized is a string that is a canonical representation of the document
|
272 | // that can be used for hashing, comparison, etc.
|
273 | ```
|
274 |
|
275 | ### <a name="tordf"></a>toRDF (N-Quads)
|
276 |
|
277 | ```js
|
278 | // serialize a document to N-Quads (RDF)
|
279 | const nquads = await jsonld.toRDF(doc, {format: 'application/n-quads'});
|
280 | // nquads is a string of N-Quads
|
281 | ```
|
282 |
|
283 | ### <a name="fromrdf"></a>fromRDF (N-Quads)
|
284 |
|
285 | ```js
|
286 | // deserialize N-Quads (RDF) to JSON-LD
|
287 | const doc = await jsonld.fromRDF(nquads, {format: 'application/n-quads'});
|
288 | // doc is JSON-LD
|
289 | ```
|
290 |
|
291 | ### Custom RDF Parser
|
292 |
|
293 | ```js
|
294 | // register a custom synchronous RDF parser
|
295 | jsonld.registerRDFParser(contentType, input => {
|
296 | // parse input to a jsonld.js RDF dataset object... and return it
|
297 | return dataset;
|
298 | });
|
299 |
|
300 | // register a custom promise-based RDF parser
|
301 | jsonld.registerRDFParser(contentType, async input => {
|
302 | // parse input into a jsonld.js RDF dataset object...
|
303 | return new Promise(...);
|
304 | });
|
305 | ```
|
306 |
|
307 | ### Custom Document Loader
|
308 |
|
309 | ```js
|
310 | // how to override the default document loader with a custom one -- for
|
311 | // example, one that uses pre-loaded contexts:
|
312 |
|
313 | // define a mapping of context URL => context doc
|
314 | const CONTEXTS = {
|
315 | "http://example.com": {
|
316 | "@context": ...
|
317 | }, ...
|
318 | };
|
319 |
|
320 | // grab the built-in Node.js doc loader
|
321 | const nodeDocumentLoader = jsonld.documentLoaders.node();
|
322 | // or grab the XHR one: jsonld.documentLoaders.xhr()
|
323 |
|
324 | // change the default document loader
|
325 | const customLoader = async (url, options) => {
|
326 | if(url in CONTEXTS) {
|
327 | return {
|
328 | contextUrl: null, // this is for a context via a link header
|
329 | document: CONTEXTS[url], // this is the actual document that was loaded
|
330 | documentUrl: url // this is the actual context URL after redirects
|
331 | };
|
332 | }
|
333 | // call the default documentLoader
|
334 | return nodeDocumentLoader(url);
|
335 | };
|
336 | jsonld.documentLoader = customLoader;
|
337 |
|
338 | // alternatively, pass the custom loader for just a specific call:
|
339 | const compacted = await jsonld.compact(
|
340 | doc, context, {documentLoader: customLoader});
|
341 | ```
|
342 |
|
343 | ### Node.js Document Loader User-Agent
|
344 |
|
345 | It is recommended to set a default `user-agent` header for Node.js
|
346 | applications. The default for the default Node.js document loader is
|
347 | `jsonld.js`.
|
348 |
|
349 | Related Modules
|
350 | ---------------
|
351 |
|
352 | * [jsonld-cli][]: A command line interface tool called `jsonld` that exposes
|
353 | most of the basic jsonld.js API.
|
354 | * [jsonld-request][]: A module that can read data from stdin, URLs, and files
|
355 | and in various formats and return JSON-LD.
|
356 |
|
357 | Commercial Support
|
358 | ------------------
|
359 |
|
360 | Commercial support for this library is available upon request from
|
361 | [Digital Bazaar][]: support@digitalbazaar.com
|
362 |
|
363 | Source
|
364 | ------
|
365 |
|
366 | The source code for the JavaScript implementation of the JSON-LD API
|
367 | is available at:
|
368 |
|
369 | http://github.com/digitalbazaar/jsonld.js
|
370 |
|
371 | Tests
|
372 | -----
|
373 |
|
374 | This library includes a sample testing utility which may be used to verify
|
375 | that changes to the processor maintain the correct output.
|
376 |
|
377 | The main test suites are included in external repositories. Check out each of
|
378 | the following:
|
379 |
|
380 | https://github.com/w3c/json-ld-api
|
381 | https://github.com/w3c/json-ld-framing
|
382 | https://github.com/json-ld/json-ld.org
|
383 | https://github.com/json-ld/normalization
|
384 |
|
385 | They should be sibling directories of the jsonld.js directory or in a
|
386 | `test-suites` dir. To clone shallow copies into the `test-suites` dir you can
|
387 | use the following:
|
388 |
|
389 | npm run fetch-test-suites
|
390 |
|
391 | Node.js tests can be run with a simple command:
|
392 |
|
393 | npm test
|
394 |
|
395 | If you installed the test suites elsewhere, or wish to run other tests, use
|
396 | the `JSONLD_TESTS` environment var:
|
397 |
|
398 | JSONLD_TESTS="/tmp/org/test-suites /tmp/norm/tests" npm test
|
399 |
|
400 | This feature can be used to run the older json-ld.org test suite:
|
401 |
|
402 | JSONLD_TESTS=/tmp/json-ld.org/test-suite npm test
|
403 |
|
404 | Browser testing can be done with Karma:
|
405 |
|
406 | npm run test-karma
|
407 | npm run test-karma -- --browsers Firefox,Chrome
|
408 |
|
409 | Code coverage of node tests can be generated in `coverage/`:
|
410 |
|
411 | npm run coverage
|
412 |
|
413 | To display a full coverage report on the console from coverage data:
|
414 |
|
415 | npm run coverage-report
|
416 |
|
417 | The Mocha output reporter can be changed to min, dot, list, nyan, etc:
|
418 |
|
419 | REPORTER=dot npm test
|
420 |
|
421 | Remote context tests are also available:
|
422 |
|
423 | # run the context server in the background or another terminal
|
424 | node tests/remote-context-server.js
|
425 |
|
426 | JSONLD_TESTS=`pwd`/tests npm test
|
427 |
|
428 | To generate EARL reports:
|
429 |
|
430 | # generate the EARL report for Node.js
|
431 | EARL=earl-node.jsonld npm test
|
432 |
|
433 | # generate the EARL report for the browser
|
434 | EARL=earl-firefox.jsonld npm run test-karma -- --browser Firefox
|
435 |
|
436 | To generate an EARL report with the `json-ld-api` and `json-ld-framing` tests
|
437 | as used on the official [JSON-LD Processor Conformance][] page
|
438 |
|
439 | JSONLD_TESTS="`pwd`/../json-ld-api/tests `pwd`/../json-ld-framing/tests" EARL="jsonld-js-earl.jsonld" npm test
|
440 |
|
441 | The EARL `.jsonld` output can be converted to `.ttl` using the [rdf][] tool:
|
442 |
|
443 | rdf serialize jsonld-js-earl.jsonld --output-format turtle -o jsonld-js-earl.ttl
|
444 |
|
445 | Optionally follow the [report
|
446 | instructions](https://github.com/w3c/json-ld-api/tree/master/reports) to
|
447 | generate the HTML report for inspection. Maintainers can
|
448 | [submit](https://github.com/w3c/json-ld-api/pulls) updated results as needed.
|
449 |
|
450 | Benchmarks
|
451 | ----------
|
452 |
|
453 | Benchmarks can be created from any manifest that the test system supports.
|
454 | Use a command line with a test suite and a benchmark flag:
|
455 |
|
456 | JSONLD_TESTS=/tmp/benchmark-manifest.jsonld JSONLD_BENCHMARK=1 npm test
|
457 |
|
458 | [Digital Bazaar]: https://digitalbazaar.com/
|
459 |
|
460 | [JSON-LD 1.0 API]: http://www.w3.org/TR/2014/REC-json-ld-api-20140116/
|
461 | [JSON-LD 1.0 Framing]: https://json-ld.org/spec/ED/json-ld-framing/20120830/
|
462 | [JSON-LD 1.0]: http://www.w3.org/TR/2014/REC-json-ld-20140116/
|
463 |
|
464 | [JSON-LD CG 1.1 API]: https://json-ld.org/spec/FCGS/json-ld-api/20180607/
|
465 | [JSON-LD CG 1.1 Framing]: https://json-ld.org/spec/FCGS/json-ld-framing/20180607/
|
466 | [JSON-LD CG 1.1]: https://json-ld.org/spec/FCGS/json-ld/20180607/
|
467 |
|
468 | [JSON-LD CG API latest]: https://json-ld.org/spec/latest/json-ld-api/
|
469 | [JSON-LD CG Framing latest]: https://json-ld.org/spec/latest/json-ld-framing/
|
470 | [JSON-LD CG latest]: https://json-ld.org/spec/latest/json-ld/
|
471 |
|
472 | [JSON-LD WG 1.1 API]: https://www.w3.org/TR/json-ld11-api/
|
473 | [JSON-LD WG 1.1 Framing]: https://www.w3.org/TR/json-ld11-framing/
|
474 | [JSON-LD WG 1.1]: https://www.w3.org/TR/json-ld11/
|
475 |
|
476 | [JSON-LD WG API latest]: https://w3c.github.io/json-ld-api/
|
477 | [JSON-LD WG Framing latest]: https://w3c.github.io/json-ld-framing/
|
478 | [JSON-LD WG latest]: https://w3c.github.io/json-ld-syntax/
|
479 |
|
480 | [JSON-LD Processor Conformance]: https://w3c.github.io/json-ld-api/reports
|
481 | [JSON-LD WG]: https://www.w3.org/2018/json-ld-wg/
|
482 | [JSON-LD]: https://json-ld.org/
|
483 | [Microdata]: http://www.w3.org/TR/microdata/
|
484 | [Microformats]: http://microformats.org/
|
485 | [RDFa]: http://www.w3.org/TR/rdfa-core/
|
486 | [RFC7159]: http://tools.ietf.org/html/rfc7159
|
487 | [Rollup]: https://rollupjs.org/
|
488 | [WG test suite]: https://github.com/w3c/json-ld-api/tree/master/tests
|
489 | [errata]: http://www.w3.org/2014/json-ld-errata
|
490 | [jsonld-cli]: https://github.com/digitalbazaar/jsonld-cli
|
491 | [jsonld-request]: https://github.com/digitalbazaar/jsonld-request
|
492 | [rdf-canonize-native]: https://github.com/digitalbazaar/rdf-canonize-native
|
493 | [test runner]: https://github.com/digitalbazaar/jsonld.js/blob/master/tests/test-common.js
|
494 | [test suite]: https://github.com/json-ld/json-ld.org/tree/master/test-suite
|
495 | [webpack]: https://webpack.js.org/
|