From a conversation with @thisismissem, @erincandescent, and @bengo on the fediverse, it was brought up that having a way to reverse-link an object to any containing collections would be useful for a “follow-your-nose” way of navigating to various collections of interest. streams
is defined as “various collections of interest”, but it is not semantically appropriate here because it is intended for actors to publish “streams”. context
could work, but being part of a collection isn’t necessarily purposeful in the way context
defines itself. So the following approaches are considered:
Define itemOf
as an inverse property of items
:itemOf a rdf:Property;
rdfs:label "itemOf";
rdfs:comment "Indicates that the object is included in a collection";
rdfs:domain as:Object;
rdfs:range as:Collection;
owl:inverseOf as:items.
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"itemOf":
{
"@id": "https://w3id.org/fep/xxxx/itemOf",
"@type": "@id"
}
}
],
"id": "https://domain.example/some-object",
"type": "Object",
"itemOf": "https://domain.example/some-collection"
}
Considerations
- Requires OWL reasoning to pick up on the “inverse property” relation with
items
. - The (flattened) graph doesn’t make any claims about the Collection and which
items
it contains. It just links to it by id.
Examples
Compacted without context:
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://domain.example/some-object",
"type": "Object",
"https://w3id.org/fep/xxxx/itemOf": {
"id": "https://domain.example/some-collection"
}
}
Flattened without context:
{
"@context": "https://www.w3.org/ns/activitystreams",
"@graph": [
{
"id": "https://domain.example/some-object",
"type": "Object",
"https://w3id.org/fep/xxxx/itemOf": {
"id": "https://domain.example/some-collection"
}
}
]
}
Flattened with context:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"itemOf": {
"@id": "https://w3id.org/fep/xxxx/itemOf",
"@type": "@id"
}
}
],
"@graph": [
{
"id": "https://domain.example/some-object",
"type": "Object",
"itemOf": "https://domain.example/some-collection"
}
]
}
Statements being made:
@base <https://domain.example/> .
@prefix as: <https://www.w3.org/ns/activitystreams#> .
<some-object> a <Object> .
<some-object> <https://w3id.org/fep/xxxx/itemOf> <some-collection> .
Define itemOf
as the @reverse
of items
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"itemOf":
{
"@reverse": "as:items",
"@type": "@id"
}
}
],
"id": "https://domain.example/some-object",
"type": "Object",
"itemOf": "https://domain.example/some-collection"
}
Considerations
- The (flattened) graph doesn’t make any claims about the object, it instead makes the claims about the collection (and the collection is therefore included in the graph as a subject).
- Does not require defining a term, since you can reuse
items
with@reverse
- If a context is not used, then you will have to deal with the
@reverse
key and its structure.
- If a context is not used, then you will have to deal with the
Examples
Compacted without context:
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://domain.example/some-object",
"@reverse": {
"items": "https://domain.example/some-collection"
},
"type": "Object"
}
Flattened without context:
{
"@context": "https://www.w3.org/ns/activitystreams",
"@graph": [
{
"id": "https://domain.example/some-collection",
"items": "https://domain.example/some-object"
},
{
"id": "https://domain.example/some-object",
"type": "Object"
}
]
}
Flattened with context (note that this is the same as without context, and it doesn’t restore the itemOf
property in the flattened object):
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"itemOf": {
"@reverse": "as:items",
"@type": "@id"
}
}
],
"@graph": [
{
"id": "https://domain.example/some-collection",
"items": "https://domain.example/some-object"
},
{
"id": "https://domain.example/some-object",
"type": "Object"
}
]
}
Statements being made:
@base <https://domain.example/> .
@prefix as: <https://www.w3.org/ns/activitystreams#> .
<some-object> a <https://www.w3.org/ns/activitystreams#Object> .
<some-collection> <https://www.w3.org/ns/activitystreams#items> <some-object> .
Comparing the above approaches
I guess it comes down to whether you want to represent the inverse claim either indirectly (as in the case of defining a property) or directly (as in the case of using JSON-LD @reverse
). The indirect claim would be made on the object, and the direct claim would be made on the collection.
You could even use two different terms to define both senses separately? Perhaps itemOf
can refer to the inverse property of items
, while reverseItems
can refer to the JSON-LD @reverse
?
Posting this to get feedback before submitting it as a FEP.