-
1.
JSON-LD
JSON for Linked Data
Gregg Kellogg
gregg@greggkellogg.net
@gkellogg
-
2.
JSON-LD
JSON for Linked Data
nk ing
Li
Gregg Kellogg
gregg@greggkellogg.net
@gkellogg
-
3.
JSON
JSON has taken over service APIs
-
4.
Tower of Babel
-
5.
Tower of Babel
GitHub
{
"type": "User",
"followers": 35,
"html_url": "https://github.com/gkellogg",
"hireable": true,
"created_at": "2009-01-13T16:58:46Z",
"public_repos": 44,
"blog": "http://greggkellogg.net",
"bio": "Gregg is a Standards Architect ...",
"gravatar_id":
"42f948adff3afaa52249d963117af7c8",
"following": 35,
"company": "Self",
"public_gists": 4,
"location": "San Rafael, CA",
"name": "Gregg Kellogg",
"email": "gregg@kellogg-assoc.com",
"url": "https://api.github.com/users/gkellogg",
"avatar_url": "...",
"id": 46296,
"login": "gkellogg"
-
6.
Tower of Babel
GitHub Twitter
{
{ "max_id": 195520745634406400,
"type": "User", "page": 1,
"followers": 35, "query": "%40gkellogg",
"html_url": "https://github.com/gkellogg", "results": [{
"hireable": true, "created_at": "Thu, 26 Apr 2012 14:32:33
"created_at": "2009-01-13T16:58:46Z", +0000",
"public_repos": 44, "from_user": "kendall",
"blog": "http://greggkellogg.net", "from_user_name": "Kendall Clark",
"bio": "Gregg is a Standards Architect ...", "id": 195520745634406400,
"gravatar_id": "in_reply_to_status_id":
"42f948adff3afaa52249d963117af7c8", 195518881811529729,
"following": 35, "iso_language_code": "en",
"company": "Self", "metadata": {"result_type": "recent"},
"public_gists": 4, "text": "@Gkellogg Multiple resources in a
"location": "San Rafael, CA", single JSON-LD struct/doc/message.",
"name": "Gregg Kellogg", "to_user": "Gkellogg",
"email": "gregg@kellogg-assoc.com", "to_user_id": 6125262,
"url": "https://api.github.com/users/gkellogg", "to_user_name": "Gregg Kellogg"
"avatar_url": "...", }],
"id": 46296, "results_per_page": 1,
"login": "gkellogg" "since_id": 0,
"since_id_str": "0"
}
-
7.
Tower of Babel
GitHub Twitter Facebook
{
{ "max_id": 195520745634406400, {
"type": "User", "page": 1, "id": "1236600216",
"followers": 35, "query": "%40gkellogg", "name": "Gregg Kellogg",
"html_url": "https://github.com/gkellogg", "results": [{ "first_name": "Gregg",
"hireable": true, "created_at": "Thu, 26 Apr 2012 14:32:33 "last_name": "Kellogg",
"created_at": "2009-01-13T16:58:46Z", +0000", "link": "https://www.facebook.com/
"public_repos": 44, "from_user": "kendall", gkellogg",
"blog": "http://greggkellogg.net", "from_user_name": "Kendall Clark", "username": "gkellogg",
"bio": "Gregg is a Standards Architect ...", "id": 195520745634406400, "gender": "male",
"gravatar_id": "in_reply_to_status_id": "locale": "en_US"
"42f948adff3afaa52249d963117af7c8", 195518881811529729, }
"following": 35, "iso_language_code": "en",
"company": "Self", "metadata": {"result_type": "recent"},
"public_gists": 4, "text": "@Gkellogg Multiple resources in a
"location": "San Rafael, CA", single JSON-LD struct/doc/message.",
"name": "Gregg Kellogg", "to_user": "Gkellogg",
"email": "gregg@kellogg-assoc.com", "to_user_id": 6125262,
"url": "https://api.github.com/users/gkellogg", "to_user_name": "Gregg Kellogg"
"avatar_url": "...", }],
"id": 46296, "results_per_page": 1,
"login": "gkellogg" "since_id": 0,
"since_id_str": "0"
}
-
8.
Introducing JSON-LD
@graph
@context
@id
JSON-based syntax to express linked data
@language
@value
@list
@type @set
-
9.
Self-describing Messages
• Give objects types {
"@context": {
(@type) "schema": "http://schema.org/",
"Person": "schema:Person",
"colleagues": {"@id": "schema:colleagues", "@type": "@id"},
"name": "schema:name",
"image": {"@id": "schema:image", "@type": "@id"},
"url": {"@id": "schema:url", "@type": "@id"}
}
}
{
"@context": "http://example.com/context.jsonld",
"@type": "Person",
"image": "http://localhost:9393/examples/schema.org/janedoe.jpg",
"colleagues": [
"http://www.xyz.edu/students/alicejones.html",
"http://www.xyz.edu/students/bobsmith.html"
],
"name": "Jane Doe",
"url": "http://www.janedoe.com"
}
-
10.
Self-describing Messages
• Give objects types {
"@context": {
(@type) "schema": "http://schema.org/",
"Person": "schema:Person",
•
"colleagues": {"@id": "schema:colleagues", "@type": "@id"},
Associate properties "name": "schema:name",
"image": {"@id": "schema:image", "@type": "@id"},
with IRIs "url": {"@id": "schema:url", "@type": "@id"}
}
}
{
"@context": "http://example.com/context.jsonld",
"@type": "Person",
"image": "http://localhost:9393/examples/schema.org/janedoe.jpg",
"colleagues": [
"http://www.xyz.edu/students/alicejones.html",
"http://www.xyz.edu/students/bobsmith.html"
],
"name": "Jane Doe",
"url": "http://www.janedoe.com"
}
-
11.
Self-describing Messages
• Give objects types {
"@context": {
(@type) "schema": "http://schema.org/",
"Person": "schema:Person",
•
"colleagues": {"@id": "schema:colleagues", "@type": "@id"},
Associate properties "name": "schema:name",
"image": {"@id": "schema:image", "@type": "@id"},
with IRIs "url": {"@id": "schema:url", "@type": "@id"}
}
•
}
Use terms defined in a
referenced context {
"@context": "http://example.com/context.jsonld",
"@type": "Person",
"image": "http://localhost:9393/examples/schema.org/janedoe.jpg",
"colleagues": [
"http://www.xyz.edu/students/alicejones.html",
"http://www.xyz.edu/students/bobsmith.html"
],
"name": "Jane Doe",
"url": "http://www.janedoe.com"
}
-
12.
Self-describing Messages
• Give objects types {
"@context": {
(@type) "schema": "http://schema.org/",
"Person": "schema:Person",
•
"colleagues": {"@id": "schema:colleagues", "@type": "@id"},
Associate properties "name": "schema:name",
"image": {"@id": "schema:image", "@type": "@id"},
with IRIs "url": {"@id": "schema:url", "@type": "@id"}
}
•
}
Use terms defined in a
referenced context {
"@context": "http://example.com/context.jsonld",
"@type": "Person",
• Specify property types
"image": "http://localhost:9393/examples/schema.org/janedoe.jpg",
"knows": [
"http://www.xyz.edu/students/alicejones.html",
in context "http://www.xyz.edu/students/bobsmith.html"
],
"name": "Jane Doe",
"url": "http://www.janedoe.com"
}
-
13.
Language Principles
-
14.
• Make full use of JSON syntactic
{
"@context": "http://json-ld.org/contexts/person",
representations "@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
• Object defines a subject "name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
definition }
-
15.
• Make full use of JSON syntactic
{
"@context": "http://json-ld.org/contexts/person",
representations "@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
• Object defines a subject "name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
definition }
• Also used for subject
reference and value { "@id": "http://greggkellogg.net/foaf#me" }
representations
-
16.
• Make full use of JSON syntactic
{
"@context": "http://json-ld.org/contexts/person",
representations "@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
• Object defines a subject "name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
definition }
• Also used for subject
reference and value { "@id": "http://greggkellogg.net/foaf#me" }
representations
{
"@type": "Recipe",
"name": "Mom's World Famous Banana Bread",
"ingredients": [
• Arrays describe sets of unordered
values
"3 or 4 ripe bananas, smashed",
"1 egg",
"3/4 cup of sugar"
],
• Single values can skip array "nutrition": [{
"@type": ["NutritionInformation"],
"calories": ["240 calories"],
"fatContent": ["9 grams fat"]
}]
}
-
17.
• Define terms to use short {
"@id": "http://greggkellogg.net/foaf#me",
property names "@type": "http://schema.org/Person",
"http://schema.org/name": "Gregg Kellogg",
• Convenient for JavaScript “.” "http://schema.org/knows": {
"@id": "http://www.markus-lanthaler.com/"
notation }
}
{
"@context": {
"Person": "http://schema.org/Person",
"name": "http://schema.org/name",
"knows”: "http://schema.org/knows"
},
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": {"@id": "http://www.markus-lanthaler.com/"}
}
-
18.
• Define terms to use short {
"@id": "http://greggkellogg.net/foaf#me",
property names "@type": "http://schema.org/Person",
"http://schema.org/name": "Gregg Kellogg",
• Convenient for JavaScript “.” "http://schema.org/knows": {
"@id": "http://www.markus-lanthaler.com/"
notation }
}
• Add @type coercions to
use simple string value.
{
"@context": {
"schema": "http://schema.org/",
"Person": "schema:Person",
"name": "schema:name",
"knows”: {
"@id": "schema:knows",
"@type": "@id"
},
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
}
-
19.
• Define terms to use short {
"@id": "http://greggkellogg.net/foaf#me",
property names "@type": "http://schema.org/Person",
"http://schema.org/name": "Gregg Kellogg",
• Convenient for JavaScript “.” "http://schema.org/knows": {
"@id": "http://www.markus-lanthaler.com/"
notation }
}
• Add @type coercions to
use simple string value.
{
"@context": {
"schema": "http://schema.org/",
"Person": "schema:Person",
• Use external @context. "name": "schema:name",
"knows”: {
"@id": "schema:knows",
"@type": "@id"
}
}
{
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
}
-
20.
•
{
Define referenced subject "@context": "http://json-ld.org/contexts/person",
definition with chaining "@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": {
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
}
-
21.
•
{
Define referenced subject "@context": "http://json-ld.org/contexts/person",
definition with chaining "@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": {
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
}
{
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
• Add @language to values. "@type": "Person",
"name": "Gregg Kellogg",
"honorificSuffix": {"@value": "M.S.", "@language": "en"},
"knows": {
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"honorificSuffix": {"@value": "Dipl.Ing.", "@language": "de"},
"knows" "http://greggkellogg.net/foaf#me"
}
}
-
22.
• Add @type to values. {
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
• Link to externally defined "@type": "Person",
"name": "Gregg Kellogg",
resources. "birthDate": {"@value": "1957-02-27", "@type": "xsd:date"},
"honorificSuffix": {"@value": "M.S.", "@language": "en"},
"knows": "http://www.markus-lanthaler.com/"
}
-
23.
• Add property @type and {
"@context": {
@language definitions to "schema": "http://schema.org/",
context "Person": "schema:Person",
"name": "schema:name",
"birthDate”: {
"@id": "schema: birthDate","@type": "xsd:date"
},
"honorificSuffix”: {
"@id": "schema:honorificSuffix","@language": "en"
},
"knows”: {"@id": "schema:knows","@type": "@id"}
},
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"birthDate": "1957-02-27",
"honorificSuffix": "M.S.",
"knows": "http://www.markus-lanthaler.com/"
}
-
24.
• More features defined in the syntax
specification*:
• @set, @list, Compact IRIs, Unlabeled
Nodes
• Embedded @context definitions
• Named Graphs
* http://json-ld.org/spec/latest/json-ld-syntax
-
25.
Examples “In the Wild”
-
26.
DBpedia
{
"@graph": [
{
"@id": "http://dbpedia.org/resource/DBpedia",
"http://dbpedia.org/property/genre" : [ "http://dbpedia.org/resource/Linked_Data" ]
},
{
"@id": "http://dbpedia.org/resource/Linked_Data",
"@type" : [ "http://dbpedia.org/class/yago/Buzzwords" ] ,
"http://www.w3.org/2002/07/owl#sameAs" : ["http://rdf.freebase.com/ns/m/02r2kb1"] ,
"http://www.w3.org/2000/01/rdf-schema#comment": [
{ "@value" : "Linked Open Data (LOD) bezeichnet ..." , "@language" : "de" } ,
{ "@value" : "In computing, linked Data describes ..." , "@language" : "en" } ],
"http://purl.org/dc/terms/subject" : [
"http://dbpedia.org/resource/Category:World_Wide_Web" ,
"http://dbpedia.org/resource/Category:Buzzwords" ,
"http://dbpedia.org/resource/Category:Semantic_Web"
],
...
}]
}
http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=DESCRIBE+<http://dbpedia.org/resource/
Linked_Data>&output=application%2Fld%2Bjson
-
27.
Schema.org
Using RDFa to JSON-LD bookmarklet*
http://linter.structured-data.org/examples/
schema.org/sdo_eg_rdfa_12.html
* bookmarklet courtesy of Niklas Lindström
-
28.
Schema.org
{
"@context": {...},
Using RDFa to JSON-LD bookmarklet* "@graph": [{
"@id": "http://linter.structured-data.org/examples/schema.org/Recipe.rdfa",
"rdfa:usesVocabulary": "http://schema.org/"
}, {
"@type": ["Recipe"],
"name": ["Mom's World Famous Banana Bread"],
"author": ["John Smith"],
"publishDate": ["2009-05-08"],
"image": [{"@id": ".../bananabread.jpg"}],
http://linter.structured-data.org/examples/ "description": ["This classic banana bread recipe ..."],
schema.org/sdo_eg_rdfa_12.html "prepTime": ["PT15M"],
"cookTime": ["PT1H"],
"recipeYield": ["1 loaf"],
"nutrition": [{
"@type": ["NutritionInformation"],
"calories": ["240 calories"],
"fatContent": ["9 grams fat"]
}],
"ingredients": [
"3 or 4 ripe bananas, smashed",
"1 egg",
"3/4 cup of sugar"
],
"recipeInstructions": ["Preheat the oven to 350 degrees..."],
"interactionCount": ["UserComments:140"]
}]
* bookmarklet courtesy of Niklas Lindström
}
-
29.
Drupal
http://directory.occupy.net/node/20080.jsonld
-
30.
Drupal
{
"@context": "http://drupal.example.org/context.jsonld",
"@id": "http://directory.occupy.net/occupation/al/occupy-
prishtina",
"@type": ["ows:Occupation", "schema:Organization"],
"foaf:name": "Occupy Prishtina",
"schema:name": "Occupy Prishtina",
"dc:date": "2012-02-12T21:18:08-05:00",
"dc:created": "2012-02-12T21:18:08-05:00",
"dc:modified": "2012-02-12T21:57:52-05:00",
"sioc:num_replies": 0,
"schema:foundingDate": "2011-10-15T00:00:00-04:00",
"ows:twitter_account": "@OccupyPrishtina",
"foaf:mbox": "",
"schema:telephone": "",
"foaf:phone": ""
}
http://directory.occupy.net/node/20080.jsonld
-
31.
PaySwarm
{
"@context": "http://purl.org/payswarm/v1",
"@graph": {
"@type": "Transaction",
"transfer": {
"@type": "Transfer",
Named "amount": "7.50",
Graph "currency": "USD",
"source": "https://bluebank.com/people/manu/accounts/food",
"destination": "https://redbank.com/people/gregg/accounts/hosting",
"comment": "Chipping in for the Pizza Party tomorrow."
},
},
"signature": {
"@type": "JsonLdSignature",
Signature of "created": "2011-09-23T20:21:34Z",
"signer": "http://bluebank.com/people/manu/keys/5",
Named "signatureValue": "ExMgoDIyOGQzNGVkM...mOWM32Nj4NTIyZTkZDYMI="
Graph }
}
-
32.
Working with data
• Expand documents to remove effect of @context.
{
"@context": "http://drupal.example.org/context.jsonld",
"@id": "http://directory.occupy.net/occupation/al/occupy-
prishtina",
"@type": ["ows:Occupation", "schema:Organization"],
"foaf:name": "Occupy Prishtina",
"schema:name": "Occupy Prishtina",
"dc:date": "2012-02-12T21:18:08-05:00",
"dc:created": "2012-02-12T21:18:08-05:00",
"dc:modified": "2012-02-12T21:57:52-05:00",
"sioc:num_replies": 0,
"schema:foundingDate": "2011-10-15T00:00:00-04:00",
"ows:twitter_account": "@OccupyPrishtina",
"foaf:mbox": "",
"schema:telephone": "",
"foaf:phone": ""
}
-
33.
Working with data
• Expand documents to remove effect of @context.
[{
"@id": "http://directory.occupy.net/occupation/al/occupy-prishtina",
{ "@type": ["http://vocab.occupy.net/ows#Occupation", "http://schema.org/Organization"],
"@context": "http://drupal.example.org/context.jsonld", "http://purl.org/dc/terms/created": [{
"@id": "http://directory.occupy.net/occupation/al/occupy- "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
"@value": "2012-02-12T21:18:08-05:00"
prishtina",
}],
"@type": ["ows:Occupation", "schema:Organization"], "http://purl.org/dc/terms/date": [{
"foaf:name": "Occupy Prishtina", "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
"schema:name": "Occupy Prishtina", "@value": "2012-02-12T21:18:08-05:00"
}],
"dc:date": "2012-02-12T21:18:08-05:00",
"http://purl.org/dc/terms/modified": [{
"dc:created": "2012-02-12T21:18:08-05:00", "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
"dc:modified": "2012-02-12T21:57:52-05:00", "@value": "2012-02-12T21:57:52-05:00"
"sioc:num_replies": 0, }],
"http://rdfs.org/sioc/ns#num_replies": [{
"schema:foundingDate": "2011-10-15T00:00:00-04:00",
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"ows:twitter_account": "@OccupyPrishtina", "@value": "0"
"foaf:mbox": "", }],
"schema:telephone": "", "http://schema.org/foundingDate": [{
"@type": "http://www.w3.org/2001/XMLSchema#date",
"foaf:phone": ""
"@value": "2011-10-15T00:00:00-04:00"
} }],
"http://schema.org/name": ["Occupy Prishtina"],
"http://schema.org/telephone": [""],
"http://vocab.occupy.net/ows#twitter_account": ["@OccupyPrishtina"],
"http://xmlns.com/foaf/0.1/mbox": [""],
"http://xmlns.com/foaf/0.1/name": ["Occupy Prishtina"],
"http://xmlns.com/foaf/0.1/phone": [""]
}]
-
34.
Working with data
• Compact documents to apply a @context.
[{
"@id": "http://directory.occupy.net/occupation/al/occupy-prishtina",
"@type": ["http://vocab.occupy.net/ows#Occupation", "http://schema.org/Organization"],
"http://purl.org/dc/terms/created": [{
"@type": "http://www.w3.org/2001/XMLSchema#dateTime",
"@value": "2012-02-12T21:18:08-05:00"
}],
"http://purl.org/dc/terms/date": [{
"@type": "http://www.w3.org/2001/XMLSchema#dateTime",
"@value": "2012-02-12T21:18:08-05:00"
}],
"http://purl.org/dc/terms/modified": [{
"@type": "http://www.w3.org/2001/XMLSchema#dateTime",
"@value": "2012-02-12T21:57:52-05:00"
}],
"http://rdfs.org/sioc/ns#num_replies": [{
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": "0"
}],
"http://schema.org/foundingDate": [{
"@type": "http://www.w3.org/2001/XMLSchema#date",
"@value": "2011-10-15T00:00:00-04:00"
}],
"http://schema.org/name": ["Occupy Prishtina"],
"http://schema.org/telephone": [""],
"http://vocab.occupy.net/ows#twitter_account": ["@OccupyPrishtina"],
"http://xmlns.com/foaf/0.1/mbox": [""],
"http://xmlns.com/foaf/0.1/name": ["Occupy Prishtina"],
"http://xmlns.com/foaf/0.1/phone": [""]
}]
-
35.
Working with data
• Compact documents to apply a @context.
[{
"@id": "http://directory.occupy.net/occupation/al/occupy-prishtina",
{
"@type": ["http://vocab.occupy.net/ows#Occupation", "http://schema.org/Organization"], "@context": "http://drupal.example.org/context.jsonld",
"http://purl.org/dc/terms/created": [{ "@id": "http://directory.occupy.net/occupation/al/occupy-
"@type": "http://www.w3.org/2001/XMLSchema#dateTime", prishtina",
"@value": "2012-02-12T21:18:08-05:00" "@type": ["ows:Occupation", "schema:Organization"],
}],
"http://purl.org/dc/terms/date": [{ "foaf:name": "Occupy Prishtina",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime", "schema:name": "Occupy Prishtina",
"@value": "2012-02-12T21:18:08-05:00" "dc:date": "2012-02-12T21:18:08-05:00",
}], "dc:created": "2012-02-12T21:18:08-05:00",
"http://purl.org/dc/terms/modified": [{
"@type": "http://www.w3.org/2001/XMLSchema#dateTime", "dc:modified": "2012-02-12T21:57:52-05:00",
"@value": "2012-02-12T21:57:52-05:00" "sioc:num_replies": 0,
}], "schema:foundingDate": "2011-10-15T00:00:00-04:00",
"http://rdfs.org/sioc/ns#num_replies": [{ "ows:twitter_account": "@OccupyPrishtina",
"@type": "http://www.w3.org/2001/XMLSchema#integer",
"@value": "0" "foaf:mbox": "",
}], "schema:telephone": "",
"http://schema.org/foundingDate": [{ "foaf:phone": ""
"@type": "http://www.w3.org/2001/XMLSchema#date", }
"@value": "2011-10-15T00:00:00-04:00"
}],
"http://schema.org/name": ["Occupy Prishtina"],
"http://schema.org/telephone": [""],
"http://vocab.occupy.net/ows#twitter_account": ["@OccupyPrishtina"],
"http://xmlns.com/foaf/0.1/mbox": [""],
"http://xmlns.com/foaf/0.1/name": ["Occupy Prishtina"],
"http://xmlns.com/foaf/0.1/phone": [""]
}]
-
36.
Working with data
• Frame documents to impose structure
input
{
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
"ex": "http://example.org/vocab#",
"contains": {"@type": "@id"}
},
"@graph": [{
"@id": "http://example.org/test/#library",
"@type": "ex:Library",
"ex:contains": "http://example.org/test#book"
}, {
"@id": "http://example.org/test#book",
"@type": "ex:Book",
"dc:contributor": "Writer",
"dc:title": "My Book",
"ex:contains": "http://example.org/test#chapter"
}, {
"@id": "http://example.org/test#chapter",
"@type": "ex:Chapter",
"dc:description": "Fun",
"dc:title": "Chapter One"
}]
}
-
37.
Working with data
• Frame documents to impose structure
input frame
{ {
"@context": { "@context": {
"dc": "http://purl.org/dc/elements/1.1/", "dc": "http://purl.org/dc/elements/1.1/",
"ex": "http://example.org/vocab#", "ex": "http://example.org/vocab#",
"contains": {"@type": "@id"} "contains": {“@id”: “ex:contains”, "@type": "@id",
}, “title”: “dc:title”
"@graph": [{ },
"@id": "http://example.org/test/#library", "@type": "ex:Library",
+
"@type": "ex:Library", "contains": {
"ex:contains": "http://example.org/test#book" "@type": "ex:Book",
}, { "contains": {
"@id": "http://example.org/test#book", "@type": "ex:Chapter"
"@type": "ex:Book", }
"dc:contributor": "Writer", }
"dc:title": "My Book", }
"ex:contains": "http://example.org/test#chapter"
}, {
"@id": "http://example.org/test#chapter",
"@type": "ex:Chapter",
"dc:description": "Fun",
"dc:title": "Chapter One"
}]
}
-
38.
Working with data
• Frame documents to impose structure
input frame output
{ {
{
"@context": { "@context": {
"@context": {
"dc": "http://purl.org/dc/elements/1.1/", "dc": "http://purl.org/dc/elements/1.1/",
"dc": "http://purl.org/dc/elements/1.1/",
"ex": "http://example.org/vocab#", "ex": "http://example.org/vocab#",,
"ex": "http://example.org/vocab#",
"contains": {“@id”: “ex:contains”, "@type": "@id", "contains": {“@id”: “ex:contains”, "@type": "@id"
"contains": {"@type": "@id"}
“title”: “dc:title” “title”: “dc:title”
},
}, },
"@graph": [{
"@type": "ex:Library", "@graph": [{
"@id": "http://example.org/test/#library", "@id": "http://example.org/test/#library",
+
"@type": "ex:Library", "contains": {
"@type": "ex:Book", "@type": "ex:Library",
"ex:contains": "http://example.org/test#book"
"contains": { "contains": {
}, {
"@type": "ex:Chapter" "@id": "http://example.org/test#book",
"@id": "http://example.org/test#book",
} "@type": "ex:Book",
"@type": "ex:Book",
} "dc:contributor": "Writer",
"dc:contributor": "Writer",
} "title": "My Book",
"dc:title": "My Book", "contains": {
"ex:contains": "http://example.org/test#chapter" "@id": "http://example.org/test#chapter",
}, { "@type": "ex:Chapter",
"@id": "http://example.org/test#chapter", "dc:description": "Fun",
"@type": "ex:Chapter", "title": "Chapter One"
"dc:description": "Fun", }
"dc:title": "Chapter One" }
}] }]
} }
JavaScript object path: data[‘@graph][0].contains.contains.title
-
39.
Retrofit existing APIs
GET /foaf.json HTTP/1.1
Host: greggkellogg.net
Accept: application/json,*/*;q=0.1
====================================
HTTP/1.0 200 OK
...
Content-Type: application/json
Link: <http://json-ld.org/contexts/person>; rel="describedby"; type="application/ld+json"
{
"name": "Gregg Kellogg",
"homepage": "http://greggkellogg.net/",
"depiction": "http://twitter.com/account/profile_image/gkellogg"
}
-
40.
Macros
• Transform information
{
"type": "User",
• Add @id to data
"followers": 35,
"name": "Gregg Kellogg",
• Other programmatic
transformations
"email": "gregg@kellogg-assoc.com",
"url": "https://api.github.com/users/
gkellogg",
"avatar_url": "...",
"id": 46296,
"login": "gkellogg"
}
* json-ld-macros courtesy of Antonio Garrote
-
41.
{
Macros
"type": "User",
"followers": 35,
"name": "Gregg Kellogg",
"email": "gregg@kellogg-assoc.com",
• Transform information
"url": "https://api.github.com/users/
gkellogg",
"avatar_url": "...",
"id": 46296,
• Add @id to data
}
"login": "gkellogg"
• Other programmatic
transformations
* json-ld-macros courtesy of Antonio Garrote
-
42.
{
Macros
"type": "User",
"followers": 35,
"name": "Gregg Kellogg",
"email": "gregg@kellogg-assoc.com",
• Transform information
"url": "https://api.github.com/users/
gkellogg",
"avatar_url": "...",
"id": 46296,
• Add @id to data
{
}
+
"login": "gkellogg"
• Other programmatic
transformations
"https://api.github.com/users/*": {
"$": {
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/",
"foaf:depiction": {"@type": "@id"},
"gh": "https://api.github.com/vocabulary#"
},
"@id": [{"f:valueof": "login"},
{"f:prefix": "http://github.com/"}],
"@ns": {
"ns:default": "gh",
"ns:replace": {"avatar_url": "foaf:depiction", "name":
"foaf:name"}
},
"@only": ["avatar_url", "name", "followers"],
"@type": ["gh:User", "foaf:Person"]
}
}
}
* json-ld-macros courtesy of Antonio Garrote
-
43.
{
Macros
"type": "User",
"followers": 35,
"name": "Gregg Kellogg",
"email": "gregg@kellogg-assoc.com",
• Transform information
"url": "https://api.github.com/users/
gkellogg",
"avatar_url": "...",
"id": 46296,
• Add @id to data
{
}
+
"login": "gkellogg"
• Other programmatic
transformations
"https://api.github.com/users/*": {
"$": {
"@context": {
{
"foaf": "http://xmlns.com/foaf/0.1/",
"@context": {
"foaf:depiction": {"@type": "@id"},
"foaf": "http://xmlns.com/foaf/0.1/",
"gh": "https://api.github.com/vocabulary#"
"foaf:depiction": {"@type": "@id"},
},
"gh": "https://api.github.com/
"@id": [{"f:valueof": "login"},
vocabulary#"
{"f:prefix": "http://github.com/"}],
},
"@ns": {
"@id": "https://api.github.com/users/
"ns:default": "gh",
gkellogg",
"ns:replace": {"avatar_url": "foaf:depiction", "name":
"@type": ["gh:User", “foaf:Person”],
"foaf:name"}
"foaf:name": "Gregg Kellogg",
},
"foaf:depiction": "http://...",
"@only": ["avatar_url", "name", "followers"],
“gh:followers”: 35
"@type": ["gh:User", "foaf:Person"]
}
}
}
* json-ld-macros courtesy of Antonio Garrote
-
44.
The “LD” in JSON-LD
• IRIs are first-class http://greggkellogg.net/foaf
citizens {
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
}
http://www.markus-lanthaler.com
{
"@context": "http://json-ld.org/contexts/person",
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
-
45.
The “LD” in JSON-LD
• IRIs are first-class http://greggkellogg.net/foaf
citizens {
"@context": "http://json-ld.org/contexts/person",
• Object definitions may
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
be referenced or "name": "Gregg Kellogg",
"knows": "http://www.markus-lanthaler.com/"
embedded }
http://www.markus-lanthaler.com
{
{ "@context": "http://json-ld.org/contexts/person",
"@context": "http://json-ld.org/contexts/person", "@id": "http://www.markus-lanthaler.com/",
"@id": "http://greggkellogg.net/foaf#me", "@type": "Person",
"@type": "Person", "name": "Markus Lanthaler",
"name": "Gregg Kellogg", "knows" "http://greggkellogg.net/foaf#me"
"knows": { }
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
}
-
46.
RDF
{
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": {
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
}
-
47.
RDF
{
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": {
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
}
-
48.
RDF
{
"@context": "http://json-ld.org/contexts/person",
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": {
"@id": "http://www.markus-lanthaler.com/",
"@type": "Person",
"name": "Markus Lanthaler",
"knows" "http://greggkellogg.net/foaf#me"
}
}
@prefix: schema <http://schema.org/> .
<http://greggkellogg.net/foaf#me> a schema:Person;
schema:name “Gregg Kellogg”;
shema:knows <http://www.markus-lanthaler.com/> .
<http://www.markus-lanthaler.com/> a schema:Person
schema:name “Markus Lanthaler”
schema:knows <http://greggkellogg.net/foaf#me> .
-
49.
JSON-LD API
• compact – use minimal representation
using a supplied @context
• expand – expand to full form, removing
embedded @context definitions
• frame – query for JSON-LD
• fromRDF/toRDF
-
50.
More Information
json-ld.org JavaScript
Ruby
w3c Python
PHP
Java
Gregg Kellogg C++
gregg@greggkellogg.net
http://greggkellogg.net/
http://www.slideshare.net/gkellogg1/json-for-linked-data
@gkellogg
\n
\n
JSON is widely used for RESTful APIs, but there is no standard convention on representation, or the meaning of properties and values.\n
JSON is widely used for RESTful APIs, but there is no standard convention on representation, or the meaning of properties and values.\n
JSON is widely used for RESTful APIs, but there is no standard convention on representation, or the meaning of properties and values.\n
JSON-LD brings a standard representation for expressing entity-value relationships using a few standard keywords and a consistent organizational structure for JSON Objects.\nObjects represent entities, with keys acting as properties.\n Properties always expand to full IRIs.\nArrays express a set of values associated with a property, unordered by default.\n Order expressed in @context or as an expanded value representation.\nValues are Object, string or native, with standard XSD representations for native types.\n Expanded form allows for more datatype and language variations.\n
The @type key gives an object with one or more types, described with an IRI.\nThe @context provides a way to express IRIs as simple terms, and allows values to be typed.\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Subject reference identifies an object with @id in the same document, or references an external document (Linked Data).\n
\n
\n
\n
\n
DBPedia currently uses a slightly out-of-date representation JSON-LD. But, by changing &#x201C;@id&#x201D; to &#x201C;@graph&#x201D;, and providing a context to identify IRIs, it can be processed as JSON-LD.\n
RDFa to JSON-LD bookmarklet can turn RDFa directly into JSON-LD.\n
\n
Payswarm uses named graphs to be able to sign data. The signature in the default graph signs the content of the named graph, through a separate normalization step.\n
Expansion is a core JSON-LD algorithm, used to normalize input documents to aide in processing.\n
Compaction creates a more human-readable form, but is often used as the final step in framing.\n
Framing is like SPARQL for JSON-LD, allows documents to be restructured using @type and property definitions and object relationships.\n
Framing is like SPARQL for JSON-LD, allows documents to be restructured using @type and property definitions and object relationships.\n
Normal JSON can be made JSON-LD by adding an external context through an HTTP link relation.\n
JSON-LD macros can turn more ideomatic JSON into conforming JSON-LD with standardized transformation.\n
JSON-LD macros can turn more ideomatic JSON into conforming JSON-LD with standardized transformation.\n
JSON-LD macros can turn more ideomatic JSON into conforming JSON-LD with standardized transformation.\n
JSON-LD macros can turn more ideomatic JSON into conforming JSON-LD with standardized transformation.\n
\n
\n
Full transformation from and to the RDF data model as a normative part of the API.\n
Full transformation from and to the RDF data model as a normative part of the API.\n
\n
\n