sgo.to

Feeds JSON-LD

The other day I was looking into using feeds in JSON-LD and I couldn't find anything off the shelf:

  1. RSS/ATOM are awesome, but XML.
  2. http://schema.org/DataFeed can get into JSON-LD, but is incomplete compared to RSS/ATOM.
  3. http://jsonfeed.org is JSON, but neither JSON-LD nor a perfect mapping to RSS/ATOM (e.g. re-invents it).

Ideally, I'd find something that reused as much as possible the hard work put into figuring the semantics of RSS/ATOM (as well as things like tooling, documentation, test of time, etc) but could be embedded in JSON-LD.

Here is what I'm generally looking for and here is an example of what that would look like for this website.

WDYT?

{
"@context": "http://www.w3.org/ns/Atom",
"@type": "Feed",
"title": "Sam's blog",
"subtitle": "The most awesome blog ever.",
"entries": [{
"title": "Atom/RSS json-ld",
"updated": "2003-12-13T18:30:02Z",
"content": {
"type": "xhtml",
"value": "Atom/RSS in JSON-LD!!"
}
}
]
}

Extensions

Markus Lanthaler taught me a really neat trick in JSON-LD that enables you to intermingle multiple JSON-LD contexts. This is super neat because it enables us to de-couple the vocabularies that can be concerned separately.

schema.org

For example, if you wanted to use Feed purely as a transport mechanism for schema.org data, you could easily intermingle both things:

{
"@context": "http://www.w3.org/ns/Atom",
"@type": "Feed",
"title": "Example Feed",
"entries": [{
"content": {
"@context": "https://schema.org",
"@type": "Product",
"name": "Tide",
"description": "The best detergent ever!"
}
}
]
}

Another concrete example would be re-using the schema.org definitions of Person for author metadata. For example:

{
"@context": "http://www.w3.org/ns/Atom",
"@type": "Feed",
"title": "Example Feed",
"author": {
"@context": "https://schema.org",
"@type": "Person",
"name": "Sam Goto",
"url": "http://sgo.to"
}
}

ActivityStreams

Another very interesting use case for extensions is to augment for Feed with social data, like https://www.w3.org/ns/activitystreams. For example:

{
"@context": "http://www.w3.org/ns/Atom",
"@type": "Feed",
"title": "Sam's personal blog",
"entries": [{
"content": {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Like",
"summary": "Sam's like an article",
"object": "https://twitter.com/danbri/status/1026558421653381122"
}
}
]
}

Full example

{
"@context": "http://www.w3.org/ns/Atom",
"@type": "Feed",
"title": "Example Feed",
"subtitle": "A subtitle.",
"links": [{
"@type": "Link",
"href": "http://example.org/feed/",
"rel": "self"
}, {
"@type": "Link",
"href": "http://example.org/"
}],
"id": "urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6",
"updated": "2003-12-13T18:30:02Z",
"entries": [{
"title": "Atom-Powered Robots Run Amok",
"links": [{
"@type": "Link",
"href": "http://example.org/2003/12/13/atom03"
}, {
"@type": "Link",
"rel": "alternate",
"type": "text/html",
"href": "http://example.org/2003/12/13/atom03.html"
}, {
"@type": "Link",
"rel": "edit",
"href": "http://example.org/2003/12/13/atom03/edit"
}],
"id": "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
"updated": "2003-12-13T18:30:02Z",
"summary": "Some text.",
"content": {
"type": "xhtml",
"value": ""
},
"author": {
"name": "John Doe",
"email": "johndoe@example.com"
}
}
]
}

Related Work

  • http://schema.org/DataFeed
  • https://jsonfeed.org/