Skip to main content

JSON-LD @context

Where it goes​

An application/json body can't carry an @context. An application/ld+json body must carry one, and the request can't then also send a context Link header. A request takes at most one context Link header, and in an array body every item carries the same @context.

The @context sits at the top level of the payload. One further down, inside an attribute, a value, a geometry or a languageMap, is refused. A JsonProperty's json is carried verbatim, so it is exempt.

An @context is a string, an object, null, or an array of those. Anything else is refused.

What it may hold​

A user @context that declares a JSON-LD scoped context is refused, whether it arrives in the body, in a Link header or through a remote context it references.

The built-in W3C Data Integrity context is the one exception. It declares scoped contexts of its own, but the core @context names it for ngsildproof, so Andromeda treats it as part of the core @context and accepts a user @context that names it. Proofs covers what it is used for.

A cycle of @context references is refused, and so are references nested more than eight levels deep.

When a remote @context can't be fetched, the answer is 504 LdContextNotAvailable. One that is fetched but isn't JSON, or has no top-level @context, is refused.

The core @context always wins. A user context can't redefine a core term, so such a term keeps its core meaning and falls under the rule for reserved names.

How a body is read​

A request body is read under the @context it was sent with. A member written @id or @type is read as id or type. A member written under a term your @context defines for a core term is read as that core term, in every body. With {"kind": "@type"} in your @context, a member kind is read as type, and with {"v": "https://uri.etsi.org/ngsi-ld/hasValue"} a member v is read as value. A type value that names a core class through such a term is read as that class.

A member written in the shape its term's container gives is read as if it had been written without the container.

  • Under a @set term, an array of one is its single value.
  • Under a map container (@index, @id, @type, @graph), an object of one key is the value under that key.
  • Under a map container, an object of several keys is the array of the values under its keys, in written order. A value that is itself an array gives its elements their places in it.
  • The members under an alias of @nest are members of the object that holds it.

An array of several elements under a @set term is read as written. So is JSON a body holds as data, and so is any spelling your context doesn't define. Without the aliasing context, {"kind": "Property", "v": 5} is therefore a concise Property whose value is that whole object.

How a response is written​

A response names id, type and the core terms the way the core @context spells them, whatever your @context aliases. When a stored entity is read under a context with terms that alias core terms, a @set container, a map container (@index, @id, @type, @graph) or an alias of @nest, it is written without any of them. The result is always in the NGSI-LD shape.

JSON-LD @context covers how Andromeda builds response contexts and fetches remote ones.