Linked Data mit JSON-LD: Semantische Fakten statt fester Baumstruktur

Keine Kommentare

In den letzten beiden Artikeln habe ich gezeigt, wie Frontend und Backend von Webanwendungen mithilfe von JSON-LD entkoppelt werden können. Dank JSON-LD sind weder die genauen JSON-Bezeichner noch spezifische "API-Endpunkte" im Backend relevant. Bei JSON-LD kommt es nicht mehr auf die konkrete Struktur und Syntax der Daten an, sondern auf die diesen inhärente Semantik. Dies liegt daran, dass JSON-LD eben kein spezifisches Datenformat ist, sondern lediglich eine JSON-Serialisierung von Linked Data. Um die Vorteile von JSON-LD zu verstehen, ist ein Blick auf die Eigenschaften von Linked Data hilfreich.

Bisherige Artikel

  1. Schmerzloser Datenaustausch: Mit JSON-LD Backend und Frontend entkoppeln
  2. Verlinkte Daten statt hart-kodierter Endpunkte
  3. Semantische Fakten statt fester Baumstruktur

Linked Data

Nehmen wir den Datensatz aus dem letzten Artikel als Beispiel:

{
  "@context": {
    "@vocab": "https://schema.org/",
    "@base": "https://api.example/",
    "firstname": "givenName",
    "lastname": "familyName",
    "street": "streetAddress",
    "id": "@id"
  },
  "id": "persons/42",
  "firstname": "John",
  "lastname": "Doe",
  "address": {
    "id": "addresses/1337",
    "street": "Mainstreet 23"
  }
}

Ungeachtet der konkreten JSON-Struktur handelt es sich bei diesem Datensatz um zwei Ressourcen und deren Beziehungen. Die Daten lassen sich genauso gut tabellarisch darstellen:

SubjektPrädikatObjekt
https://api.example/persons/42https://schema.org/givenNameJohn
https://api.example/persons/42https://schema.org/familyNameDoe
https://api.example/persons/42https://schema.org/addresshttps://api.example/addresses/1337
https://api.example/addresses/1337https://schema.org/streetAddressMainstreet 23

Wir haben hier eine Sammlung von Fakten, die Aussagen über eine Ressource (Subjekt) treffen. Die Ressourcen sind eindeutig über IRIs identifiziert. Ebenso ist die Art der Aussage (Prädikat) durch Verwendung von IRIs semantisch eindeutig. Als Objekt einer Aussage können primitive Datentypen verwendet werden, wie z. B. die Zeichenkette "John" als givenName. Durch Verwendung von IRIs als Objekt können wir auf andere Ressourcen verweisen, so wie dies bei der Adresse der Fall ist. Da es sich bei einer IRI um eine global eindeutige ID handelt, können sogar Ressourcen über APIs hinweg miteinander verlinkt werden. Daher kommt die Bezeichnung "Linked Data". Bei HTML nutzen wir dieses Prinzip ganz selbstverständlich, in strukturierten Daten fehlen solche Links leider viel zu oft.

Über die sogenannten "Daten-Tripel" aus Subjekt, Prädikat und Objekt lassen sich beliebige Fakten formulieren. Bei diesem Datenmodell handelt es sich um das "Resource Description Framework" (RDF). RDF ist unabhängig von einer bestimmten Serialisierung, JSON-LD ist nur eine davon. Darüber hinaus gibt es zum Beispiel RDF-XML, Notation3 oder Turtle. RDF ist im akademischen Umfeld beliebt, jedoch nie in der alltäglichen Praxis von Webentwickler*innen angekommen, da die meisten Serialisierungen ungleich komplizierter zu handhaben sind als JSON.

Dies ändert sich mit JSON-LD grundlegend, da wir die Vorteile von einfach verwendbarem JSON und der starken Semantik von RDF vereinen. Egal in welcher Struktur und mit welchen Bezeichnern ein Backend Daten ans Frontend sendet: Es handelt sich dem Wesen nach stets um "Daten-Tripel", die wir in ein uns genehmes Format serialisieren können. Dies reicht von der simplen Änderung von Bezeichnern bis hin zur Umstrukturierung ganzer JSON-Bäume.

JSON-LD ermöglicht es, die Semantik der Daten losgelöst von der Serialisierung des Backends zu betrachten und die Daten in einer neuen Form zu serialisieren. Das Frontend kann dazu die Form wählen, die es für am besten geeignet hält. Im Folgenden zeige ich einige Beispiele, wie die obigen Daten im Frontend serialisiert werden können.

Eigene JSON-Bezeichner und vollständige IRIs

Das Frontend-Team entscheidet sich, die Struktur des Backends beizubehalten, aber eigene JSON-Bezeichner zu wählen und über vollständige IRIs zu verlinken. Auf die Addresse kann dann leicht über person.address zugegriffen werden. Weitere Daten werden von person.address.iri geladen.

{
  "@context": {
    "@vocab": "https://schema.org/",
    "first": "givenName",
    "last": "familyName",
    "location": "streetAddress",
    "iri": "@id"
  },
  "iri": "https://api.example/persons/42",
  "address": {
    "iri": "https://api.example/addresses/1337",
    "location": "Mainstreet 23"
  },
  "last": "Doe",
  "first": "John"
}

Flache Liste von Ressourcen

Das Frontend-Team entscheidet sich, alle Ressourcen in einer flachen Array-Liste vorzuhalten. Die Person enthält lediglich eine Referenz auf die IRI der Adresse. In dieser Form sind alle Ressourcen leicht über ihre ID zu ermitteln, ohne eine Hierarchie von Verschachtelungen durchgehen zu müssen. z.B.

data["@graph"].find((it) => it.id === "addresses/1337");
{
  "@context": {
    "@vocab": "https://schema.org/",
    "@base": "https://api.example/",
    "id": "@id"
  },
  "@graph": [
    {
      "id": "addresses/1337",
      "streetAddress": "Mainstreet 23"
    },
    {
      "id": "persons/42",
      "address": {
        "id": "addresses/1337"
      },
      "familyName": "Doe",
      "givenName": "John"
    }
  ]
}

Umkehren der Verschachtelung

Das Frontend-Team möchte eine andere Form der Verschachtelung. Hier kann das Frontend nun über address.resident auf die Person zugreifen, statt umgekehrt über person.address die Adresse einer Person zu ermitteln. Im Kontext wird dazu mit dem Schlüsselwort @reverse angegeben, dass es sich bei resident um die Beziehung https://schema.org/address handelt, jedoch Subjekt und Objekt vertauscht sind.

{
  "@context": {
    "@vocab": "https://schema.org/",
    "resident": {
      "@reverse": "address"
    },
    "uri": "@id"
  },
  "uri": "https://api.example/addresses/1337",
  "resident": {
    "uri": "https://api.example/persons/42",
    "givenName": "Doe",
    "familyName": "John"
  },
  "streetAddress": "Mainstreet 23"
}

Datenhaltung im Frontend

Da das Frontend letzlich immer "Daten-Tripel" vom Backend lädt, kann es die Sammlung dieser Tripel im Speicher vorhalten und mit jeder Antwort vom Backend um weitere Fakten anreichern. Zunächst wird z. B. die Person geladen, dann deren Adresse, dann weitere verlinkte Daten wie z. B. Geoinformationen über den Wohnort. Die Faktensammlung auf Frontend-Seite wächst, wird in eine geeignete Form gebracht und dann von Frontend-Komponenten dargestellt.

Linked Data im Frontend

Fazit

All dies ist möglich, weil es bei JSON-LD eben nicht auf die Syntax und Struktur eines JSON-Objekts ankommt, sondern die dahinterliegende Semantik entscheidend ist. Die wesentliche Frage lautet, welche Daten-Tripel ausgetauscht werden. In welcher Form diese serialisiert werden, bleibt den Teams selbst überlassen und kann unabhängig voneinander geändert werden.

Ausblick

In meinen Artikeln habe ich mich auf die Verarbeitung von Backend-Daten im Frontend fokussiert. Natürlich gilt das Gesagte aber auch für den umgekehrten Weg: Daten, die das Frontend zurück ans Backend sendet, sind mit JSON-LD ebenso unabhängig von einer konkreten Struktur. Das Backend kann darauf den eigenen Kontext anwenden und ist vor Änderungen auf Frontend-Seite gefeit. Das Gleiche gilt auch für den Datenaustausch zwischen Backend-Services. JSON-LD eignet sich zum Beispiel hervorragend, um den Datenaustausch zwischen Microservices zu realisieren oder Drittanbieter-APIs zu integrieren.

JSON-LD bietet mehr Funktionalität, als ich in meinen Artikeln unterbringen konnte. Abschließend daher noch einige Links für alle, die sich weiter mit dem Thema befassen wollen. Ich freue mich auch über Feedback in den Kommentaren.

 

Angelo Veltens arbeitet als Web-Developer bei codecentric Hamburg. Er begeistert sich sowohl für die Frontend-Entwicklung mit JavaScript, als auch die Backend-seitige Entwicklung mit Frameworks wie Grails oder Spring Boot.
Testautomatisierung auf allen Ebenen von Unit- bis Akzeptanztests, sowie der Aufbau von Continuous-Delivery-Pipelines zählen dabei ebenfalls zu seinen Stärken.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.