Description
JSON-LD 1.1 requires @type
to be an IRI...
From 3.5 Specifying the Type: https://www.w3.org/TR/json-ld11/#specifying-the-type
In Linked Data, types are uniquely identified with an IRI.
From 9.16 Keywords: https://www.w3.org/TR/json-ld11/#keywords
The @type keyword MAY be aliased and MAY be used as a key in a node object or a value object, where its value MUST be a term, IRI reference, or a compact IRI (including blank node identifiers).
So it seems pretty clear to me that the intent and also normative requirement is for every entry in @type
to be an IRI, ultimately.
...but there are documents in the wild that don't follow this...
HOWEVER: There are documents, producers, and other specs that currently exist that use raw string literals within type
which is aliased to @type
by a @context
declaration. Notably, ATProto has this to say: https://atproto.com/specs/did#did-documents
The PDS service network location for the account is found under the service array, with id ending
#atproto_pds
, and type matchingAtprotoPersonalDataServer
At the same time, there is no ATProto-specific context document or declaration: https://web.plc.directory/did/did:plc:ewvi7nxzyoun6zhxrhs64oiz
{
"@context": [ // note there is no atproto context
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://w3id.org/security/suites/secp256k1-2019/v1"
],
"alsoKnownAs": [
"at://atproto.com"
],
"id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz",
"service": [
{
"id": "#atproto_pds",
"serviceEndpoint": "https://enoki.us-east.host.bsky.network",
"type": "AtprotoPersonalDataServer" // this is a string literal, not an IRI
}
],
"verificationMethod": [
{
"controller": "did:plc:ewvi7nxzyoun6zhxrhs64oiz",
"id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto",
"publicKeyMultibase": "zQ3shunBKsXixLxKtC5qeSG9E4J5RkGN57im31pcTzbNQnm5w",
"type": "Multikey"
}
]
}
...but it doesn't seem to cause any errors?
I would expect this to be disallowed by the JSON-LD spec, but the JSON-LD Playground seems to be okay with it?
The following non-IRI value for @type
shows up in expanded form:
"@type": [
"AtprotoPersonalDataServer"
]
When compacting against an empty context, it also seemingly works:
{ // note there is no context
"@id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz",
"https://w3id.org/security#verificationMethod": {
"@id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto",
"@type": "https://w3id.org/security#Multikey",
"https://w3id.org/security#controller": {
"@id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz"
},
"https://w3id.org/security#publicKeyMultibase": {
"@type": "https://w3id.org/security#multibase",
"@value": "zQ3shunBKsXixLxKtC5qeSG9E4J5RkGN57im31pcTzbNQnm5w"
}
},
"https://www.w3.org/ns/activitystreams#alsoKnownAs": {
"@id": "at://atproto.com"
},
"https://www.w3.org/ns/did#service": {
"@id": "#atproto_pds",
"@type": "AtprotoPersonalDataServer", // this is a string literal, not an IRI
"https://www.w3.org/ns/did#serviceEndpoint": {
"@id": "https://enoki.us-east.host.bsky.network"
}
}
}
So, what gives?
Obviously the most correct thing here is to ask the ATProto people to provide a namespace and/or context document for their extension terms, but I'm wondering if the JSON-LD processing algorithms should detect these non-IRI types and possibly give a warning or error or otherwise elide them... or is it OK for these "non-IRI types" to exist?
Note that the RDF conversion to N-Quads (in the playground example above, for instance) will not output the @type
of the single item in did:service
.
This is partially due to a different problem that I'm not sure whether I should file an issue about or not -- relative IRI references for @id
. In short, it seems like #atproto_pds
is not automatically picking on the "id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz"
of the top-level object.
No matter; we can change the service node's identifier from #atproto_pds
to did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto_pds
and two additional quads get output:
<did:plc:ewvi7nxzyoun6zhxrhs64oiz> <https://www.w3.org/ns/did#service> <did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto_pds> .
<did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto_pds> <https://www.w3.org/ns/did#serviceEndpoint> <https://enoki.us-east.host.bsky.network> .
But we don't get a quad for rdf:type
. So this backs up the notion that the "non-IRI types" are at least invalid RDF.
The question that remains: are they invalid JSON-LD as well? If not, should they be? If yes, what is to be done when processing them?