json-ld / json-ld.org

JSON for Linked Data's documentation and playground site
https://json-ld.org/
Other
861 stars 152 forks source link

Using `@base` with a DID causes truncation of prefix in the playground (after the first colon?) #849

Open trwnh opened 1 week ago

trwnh commented 1 week ago

In playing around with https://github.com/w3c/json-ld-syntax/issues/446 (i.e. where @type is not an IRI), I discovered that the playground will take this:

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    {"@base": "did:plc:ewvi7nxzyoun6zhxrhs64oiz"}
  ],
  "id": "did:plc:ewvi7nxzyoun6zhxrhs64oiz",
  "service": [
    {
      "id": "#atproto_pds",
      "serviceEndpoint": "https://enoki.us-east.host.bsky.network",
      "type": "AtprotoPersonalDataServer"
    }
  ]
}

and canonize it as this:

<did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto_pds> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <did:AtprotoPersonalDataServer> .
<did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto_pds> <https://www.w3.org/ns/did#serviceEndpoint> <https://enoki.us-east.host.bsky.network> .
<did:plc:ewvi7nxzyoun6zhxrhs64oiz> <https://www.w3.org/ns/did#service> <did:plc:ewvi7nxzyoun6zhxrhs64oiz#atproto_pds> .

Note that <did:AtprotoPersonalDataServer> is being emitted as the canonization of AtprotoPersonalDataServer which is incorrect.

Tangentially, taking out the @base from the @context and absolutizing the service.id in some other way (like prefixing it with a URI) will cause the processor to emit a warning about a "relative @type reference".

Also tangentially, taking out the @base from the @context and also taking out the # from the id atproto_pds will exhibit similar behavior -- <did:atproto_pds> is emitted as the object of the quad.

{"@base": "did:plc:ewvi7nxzyoun6zhxrhs64oiz"} will do this, but {"@base": "did:plc:ewvi7nxzyoun6zhxrhs64oiz#"} will also do the same thing.

In short, the playground is behaving as if I am declaring {"@base": "did:"}; the base IRI is seemingly truncated after the first colon.

gkellogg commented 5 days ago

<did:AtprotoPersonalDataServer> is correct, according the the way IRIs are resolved. Rules are different for resolving vocabulary-relative and document-relative IRIs, and @type uses both vocabulary- and document-relative processing (different from everything else). If it were vocabulary relative, and @vocab had been set to "did:plc:ewvi7nxzyoun6zhxrhs64oiz", "AtprotoPersonalDataServer" would get appended, yielding <did:AtprotoPersonalDataServerAtprotoPersonalDataServer > (probably also not what you'd want).

Given that it is document-relative, the rules for resolving relative IRIs ( "AtprotoPersonalDataServer") are defined in RFC3886 Relative Resolution. The operative bit in 5.2.3 Merge Paths is:

return a string consisting of the reference's path component appended to all but the last segment of the base URI's path (i.e., excluding any characters after the right-most "/" in the base URI path, or excluding the entire base URI path if it does not contain any "/" characters).

The base URI has only one segment, so the relative IRI is appended to the scheme.