Search code examples
schema.orgjson-ld

JSON LD serialization from schema.org


The following example is given on the json-ld playground.

Person example(expanded):

json-ld:

{
  "@context": "http://schema.org/",
  "@type": "Person",
  "name": "Jane Doe",
  "jobTitle": "Professor",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}

after serializtion to expanded:

[
  {
    "@type": [
      "http://schema.org/Person"
    ],
    "http://schema.org/jobTitle": [
      {
        "@value": "Professor"
      }
    ],
    "http://schema.org/name": [
      {
        "@value": "Jane Doe"
      }
    ],
    "http://schema.org/telephone": [
      {
        "@value": "(425) 123-4567"
      }
    ],
    "http://schema.org/url": [
      {
        "@id": "http://www.janedoe.com"
      }
    ]
  }
]

I ask myself where does the serializer gets the information to map the properties to the right subsequent schema (name). To achieve that, it must be able to get hold on to the person json ld schema. But if I go to https://schema.org/Person I get an HTML back and not a JSON-LD file.

So where does the serialization knowledge come from?


Solution

  • Jay is correct that the knowledge comes from the @context. This can be specified in a couple of ways:

    • Inline, using an object value for @context (or an array, which includes an object),

    • By directly retrieving a context from the URL specified (e.g., https://json-ld.org/contexts/person.jsonld),

    • By having the server do context-negotiation on the request, as an HTTP request includes an Accept header preferring JSON-LD (see Interpreting JSON as JSON-LD) such as the following:

      GET /ordinary-json-document.json HTTP/1.1
      Host: example.com
      Accept: application/ld+json,application/json,*/*;q=0.1
      
    • Or, as is presently deployed by schema.org, by returning a Link header along with a GET or HEAD request identifying the location of the actual context to load (See Alternate Document Location):

      HTTP/1.1 200 OK
      ...
      Content-Type: text/html
      Link: <alternate.jsonld>; rel="alternate"; type="application/ld+json"
      

      This last case is used by schema.org because of the challenges of making HTTP Content-Negotiation work properly on certain static site generators. If you to a HEAD request at https://schema.org, you'll get back headers including the following:

    HTTP/2 200 
    link: </docs/jsonldcontext.jsonld>; rel="alternate"; type="application/ld+json"
    

    A conforming JSON-LD processor (such as on the json-ld.org playground) knows to follow this link to find the actual context.

    In the case of the Person example, "Person" and the other keys are turned into IRIs based on instructions in that context file such as the following:

    {
      "@context": {
        ...
        "schema": "http://schema.org/",
        "Person": {"@id": "schema:Person"},
        "name": { "@id": "schema:name"},
        "jobTitle": { "@id": "schema:jobTitle"},
        "telephone": { "@id": "schema:telephone"},
        "url": { "@id": "schema:url", "@type": "@id"},
        ...
      }
    }
    

    Note that in the case of "url", it also knows that the value of that property should be treated as an IRI, rather than a text string.