If the top-level ResourceMap does not specify @id, it comes out as an anonymous node rather than referring to "the document itself".
At first glance it would seem best to recommend to add
in order to identify the resource map as the retrieved resource.
However, one could imagine a poor mans ORE set up, where requesting the Aggregation itself somehow directly responds with the ResourceMap instead of doing a HTTP redirect to the ResourceMap resource:
GET http://example.com/aggregation-1 HTTP/1.1
Accept: application/ld+json
HTTP/1.1 200 OK
Content-Type: application/ld+json
Vary: Accept
{ "@context": "https://w3id.org/ore/context",
"@type": "ResourceMap",
"describes": { "@type": "Aggregation"
"@id": "http://example.com/aggregation-1"
}
}
This response is "kind of" OK by Linked Data standards, the Resource Map is not identified (bnode), but we know it exists. When parsing this, to ensure you are picking the 'right' aggregation in the resource map, the client would just have to look for:
SELECT ?aggr WHERE {
?resourceMap ore:describes ?aggr .
}
... and in this case we should NOT RECOMMEND to use describes
anywhere but the top-level.
However ORE data model has a bit stricter definition for Resource Map:
Each Resource Map MUST be identified by a single protocol-based URI, which MUST be distinct from the Aggregation identified by the Resource Map. This specification uses URI-R to denote URIs that identify Resource Maps. There MAY be multiple Resource Maps for a single Aggregation. Each Resource Map MUST have a distinct URI (rather than forming multiple Representations from a single URI-R). A deference of a URI-R results in a serialization which the assertions described above can be extracted as a set of triples that when combined form an RDF Graph that MUST conform to a well-defined structure.
So I guess the ORE JSON-LD specification should reflect this.
This can be achived by either hard-coding "@id":
{ "@id": "http://example.com/aggregation-1.jsonld"
"describes" { "@id": "http://example.com/aggregation-1" }
}
By using the empty @id and Content-Location:
GET http://example.com/aggregation-1 HTTP/1.1
Accept: application/ld+json
HTTP/1.1 200 OK
Content-Type: application/ld+json
Content-Location: http://example.com/aggregation-1.jsonld
Vary: Accept
{ "@context": "https://w3id.org/ore/context",
"@id": "",
"@type": "ResourceMap",
"describes": { "@type": "Aggregation"
"@id": "http://example.com/aggregation-1"
}
}
The second case is in many ways 'more correct' - but also easier to get wrong..
The 'best' solution is to do a classic HTTP 303 See Other to a representation-specific Resource Map:
GET http://example.com/aggregation-1 HTTP/1.1
Accept: application/ld+json
HTTP/1.1 303 See Other
Location: http://example.com/aggregation-1.jsonld
Vary: Accept
GET http://example.com/aggregation-1.jsonld HTTP/1.1
Accept: application/ld+json
HTTP/1.1 200 OK
Content-Type: application/ld+json
{ "@context": "https://w3id.org/ore/context",
"@id": "",
"@type": "ResourceMap",
"describes": { "@type": "Aggregation"
"@id": "http://example.com/aggregation-1"
}
}
A simpler best-practice could be to identify the Aggregation with a hash-based URI:
{ "@id": "http://example.com/aggregation-1"
"describes" { "@id": "http://example.com/aggregation-1#" }
}
but this would not as easily allow for multiple resource map representations.