Skip to content

Latest commit

 

History

History
155 lines (123 loc) · 6.65 KB

the-context.md

File metadata and controls

155 lines (123 loc) · 6.65 KB

A Guide to The Context

A context, in its simplest form, is nothing but a list of key-values:

"@context": {
  "P1": "https://a.b.c/attributes/P1",
  "P2": "https://a.b.c/attributes/P2",
  "P3": "https://a.b.c/attributes/P3",
  ...
}

The key (e.g. "P1") is an alias for the longer name ("https://a.b.c/attributes/P1"). That's all there is to it, just a way of avoiding to write really long strings and also, importantly, a freedom for the user to define his/her own aliases for the longnames.

When is this useful? To write short names instead of long names, the advantage is clear.

But, what about the "freedom for the user to define his/her own aliases"? Nothing like an example to illustrate this:

I am a father to my children and a husband to my wife, a son to my parents and a grandson to my grandparents.

The way I see my three children is that the are my children.
The way my three children see each other is that the other two are their siblings.

The way I see my mother is that she's my mother.
The way my wife sees my mother is that she's her mother-in-law.

Same human beings, different "viewpoints". That's pretty much what a context is, a "viewpoint".

Expansion and Compaction

An NGSi-LD broker uses the context to expand and compact the shortnames that are part of the payload data or that comes in as a URI parameter.

What is expanded/compacted, with the help of the context, inside the payload data is:

  • The Entity Type
  • The Property Names (in all levels)
  • The Relationship Names (in all levels)

The term Attribute is used to refer to Properties, Relationships, Properties-of-Properties, etc.

So, for example, if you issue a query GET /ngsi-ld/v1/entities?type=T2, then T2 will be expanded according to the current context and then looked up to find any matching entities. All entities are stored in a fully expanded way. Can't be any other way. The expanded form is the real value of the entity type, attribute name, value, etc. Before returning the resulting payload, all expandable/compactable items (entity type, attribute name, value, etc.) are compacted according to the context.

So, in this GET example:

Orion-LD uses MongoDB for storage and if you look inside, you will see the expanded form of the entities.

The Core Context

Orion-LD, just like any NGSI-LD compliant broker, has a built-in, default context. This built-in context is called the Core Context and it is found here.

The Core Context defines the core of any NGSI-LD broker and its definitions (key-values) override any user-supplied definition. When a term (entity type or attribute name) is looked up for expansion or compaction in the context, the entire context is searched to the end, and the last hit overrides any previous hit. The Core Context is the last context to be searched, and it will thus override any other context.

The Default URL

What if a term isn't found anywhere, during the lookup in the context? Well, all entity types and attribute names are expanded, and if no match is found in the provided contest (nor in the Core Context), then a special field - "@vocab" - of the Core Context is used. The value of "@vocab" is The Default URL. If you look inside the Core Contest, ypou'll find "@vocab":

"@vocab": "https://uri.etsi.org/ngsi-ld/default-context/"

So, if an attribute has the name "P13" and "P13" isn't found antwhere, then "P13" will end up expanded according to the Default URL:

"https://uri.etsi.org/ngsi-ld/default-context/P13"

Content-Type header and the Context

There are two different ways to supply the context in an NGSI-LD request:

  • via an HTTP header called Link,
  • as part of the payload.

If the context is passed in the Link HTTP header, then the Content-Type must be application/json. If in the payload data, then the Content-Type must be application/ld+json. If this is not fulfilled, Orion-LD will respond with an error.

Accept header and the Context

Just like for Content-Type, the @context of a response can be served either in the payload body or in the "Link" HTTP header. By default (or issuing "Accept: application/ld+json"), the @context comes in the payload body. If you wish to receive the @context in the "Link" HTTP header, then use the HTTP header "Accept: application/json".

For the broker, especially when dealing with Batch operations, it's preferred to receive the context in the "Link" HTTP header, and also to return the context in the "Link" HTTP header, i.e., limit the usage of application/ld+json. The only situation where application/ld+json is really necessary is when you need to use an inline context, a context that isn't served anywhere.

Passing the Context in an Orion-LD Request

To pass the context http://context.store.es/myContexts/context1.jsonld in the Link header using curl (e.g. to create an entity):

export payload='{ "id": "xxx", "type": "TTT", ... }'
curl localhost:1026/ngsi-ld/v1/entities -d "$payload" -H 'Link: <http://context.store.es/myContexts/context1.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' -H "Content-Type: application/json"

If instead you wish to pass the context inside the payload data, it would look like this:

export payload='{ "id": "xxx", "type": "TTT", "@context": "url-to-context", ... }'
curl localhost:1026/ngsi-ld/v1/entities -d "$payload" -H "Content-Type: application/ld+json"

Compound Contexts

Contexts inside the payload data can be expressed in a variety of ways:

  • A JSON String (a URL that refers the context)
    "@context": "url-to-context"`
  • A JSON Object that is the context, i.e. a list of key-values
    "@context":	{
      "P1": "https://a.b.c/attributes/P1",
      "P2": "https://a.b.c/attributes/P2",
      ...
    }
  • A JSON Array of string (that are URLs refering contexts)
    "@context":	[
      "url-to-context1",
      "url-to-context2",
      ...
    ]
  • A JSON Array of a combination of strings and objects.
    "@context":	[
      "url-to-context1",
      {
        "P1": "https://a.b.c/attributes/P1",
        "P2": "https://a.b.c/attributes/P2",
        ...
      }
    ]

If you want to learn more about contexts, please refer to documentation on JSON-LD. There is plenty out there.