Schmerzloser Datenaustausch: Mit JSON-LD Backend und Frontend entkoppeln

3 Kommentare

Viele Webanwendungen bestehen aus einem JavaScript-Frontend, das JSON-Daten aus einem Backend abruft. Der Datenaustausch basiert dabei in der Regel auf Namenskonventionen für JSON-Bezeichner und vorab festgelegten „API-Endpunkten“. Eine JSON-LD-basierte API ist eine interessante Alternative zu dieser Herangehensweise.

Der „klassische“ JSON-basierte Ansatz führt schnell zu Problemen: Eine neue Version des Backends liefert Daten unter neuen JSON-Bezeichnern aus, das Frontend wurde nicht angepasst – peng 💥 „‚undefined‘ is not an object“.

Die folgenden Handlungen sind meiner Erfahrung nach kritisch:

  1. JSON-Bezeichner werden geändert.
  2. Die Struktur der Daten wird verändert.
  3. Bestimmte Daten werden werden nicht mehr direkt ausgeliefert, sondern erfordern eine zusätzliche HTTP-Anfrage.
  4. Backend-seitig ändern sich „Endpunkte“, welche die Daten bereitstellen.

Im schlimmsten Fall kommt es zu Fehlern, weil das Frontend die Änderungen nicht berücksichtigt. Im besten Fall sind alle Beteiligten über die Änderungen informiert und machen sich an die Arbeit. Selbst dann ist es lästig, dass im Frontend überhaupt Arbeit anfällt. Zumal dies unnötig ist, wie ich zeigen möchte.

Weder sollten die genannten Änderungen zu Fehlern führen, noch sollte in langwierigen Meetings darüber diskutiert werden, wie einzelne JSON-Bezeichner lauten und wie die Daten verschachtelt werden. Die verantwortlichen Teams können dies vermeiden, indem sie den Datenaustausch von der konkreten JSON-Syntax unabhängig machen.

Du lernst,

  1. wie du unterschiedliche JSON-Bezeichner in Backend und Frontend verwenden kannst
  2. wie du Daten lädst, ohne vorab im Frontend die „Endpunkte“ zu kennen
  3. wie du das Frontend von den konkreten Datenstrukturen des Backends entkoppelst

Als erstes werden wir die JSON-Bezeichner von Frontend und Backend entkoppeln. Nehmen wir an, ein Backend liefert Daten zu einer Person als JSON-Objekt mit bestimmten Eigenschaften:

{
    "id": "42",
    "firstname": "John",
    "lastname": "Doe",
    "birthday": "1978-05-17"
}

Für gewöhnlich verlässt sich das Frontend auf die verwendeten Bezeichner. Darauf basierend wird eine Ansicht aufgebaut. Eine Funktion erzeugt bespielsweise eine Begrüßung anhand der Eigenschaften firstname und lastname:

function greet(person) {
  return `Hello, ${person.firstname} ${person.lastname}`;
}

Das Backend-Team ändert nun die ausgelieferte Datenstruktur wie folgt ab:

{
    "id": "42",
    "firstName": "John",
    "lastName": "Doe",
    "birthday": "1978-05-17"
}

Wir müssen das Frontend nun ebenfalls anpassen und die neuen Bezeichner firstName und lastName verwenden.

Um diese Abhängigkeit von den Bezeichnern aufzulösen, bietet sich die Verwendung von JSON-LD an. Bei JSON-LD handelt es sich um eine Erweiterung des JSON-Formats. Das Kürzel „LD“ steht für „Linked Data“ – was es damit auf sich hat, werden wir später noch sehen.

Um JSON-LD zu nutzen, müssen wir an den eigentlichen Backend-Daten nichts verändern. Sie müssen lediglich um einen „Kontext“ erweitert werden. Dieser Kontext beschreibt die Semantik der Daten. Ein JSON-LD Datensatz könnte in unserem Beispiel so aussehen:

{
  "@context": {
    "@vocab": "https://schema.org/",
    "firstname": "givenName",
    "lastname": "familyName",
    "birthday": "birthDate",
    "id": "@id"
  },
  "id": "42",
  "firstname": "John",
  "lastname": "Doe",
  "birthday": "1978-05-17"
}

Die eigentlichen Daten und JSON-Bezeichner haben sich nicht verändert. Wir haben dem Objekt lediglich die Eigenschaft @context hinzugefügt. Dieser Kontext legt die Bedeutung der einzelnen JSON-Bezeichner fest. In Zeile 3 besagt @vocab, dass wir das Vokabular von schema.org als Grundlage verwenden wollen. Schema.org stellt eindeutige URIs zur Auszeichnung von Daten zur Verfügung, um z.B. Inhalte aus Webseiten für Suchmaschinen verständlich zu machen. So lässt sich zum Beispiel eine Zeichenkette, die als https://schema.org/givenName ausgezeichnet ist, eindeutig als Vorname einer Person erkennen. Das Vokabular von schema.org können wir mit JSON-LD nutzen, um auch die Daten für unser Frontend auszuzeichnen.

Die nächsten Zeilen innerhalb von @context bilden die im Backend verwendeten Bezeichner auf schema.org Eigenschaften ab. Hinter dem Bezeichner firstname steckt also die Eigenschaft https://schema.org/givenName. Ebenso werden lastname und birthday semantisch ausgezeichnet. Der letzte Eintrag im Kontext gibt an, dass der Bezeichner id das Objekt eindeutig identifiziert. Dies wird später noch wichtig, wenn wir Daten vom Backend laden wollen.

Der Vorteil von JSON-LD liegt unter anderem darin, dass das Frontend seinen eigenen Kontext festlegen kann, um selbstständig die Bezeichnungen auf Frontend-Seite fest zu legen:

var context = {
  "@vocab": "https://schema.org/",
  first_name: "givenName",
  last_name: "familyName",
  birth_date: "birthDate",
  person_id: "@id"
}

Das Frontend legt mit diesem Kontext eigene Bezeichner für die schema.org-Eigenschaften fest. Indem dieser Kontext auf die Daten vom Server angewendet wird, erhält das Frontend einen Datensatz, der vor Backend-seitigen Änderungen gefeit ist:

import * as jsonld from "jsonld";
 
// Frontend-Kontext auf Backend-Daten anwenden
jsonld.compact(context, backendData, (err, person) => {
  greet(person);
});
 
function greet(person) {
  console.log(`Hello, ${person.first_name} ${person.last_name}`);
}

Die Funktion jsonld.compact stammt aus der Bibliothek jsonld.js. Sie übersetzt die Backend-Daten (backendData) in den Frontend-Kontext (context). Das Ergebnis steht der Callback-Funktion in der Variable person zur Verfügung. Diese enthält nun folgendes Objekt:

{
  "@context": {
    "@vocab": "https://schema.org/",
    "first_name": "givenName",
    "last_name": "familyName",
    "birth_date": "birthDate",
    "person_id": "@id"
  },
  "person_id": "42",
  "birth_date": "1978-05-17",
  "last_name": "Doe",
  "first_name": "John"
}

Somit konnten wir die Backend-Daten im Frontend auf selbst gewählte Bezeichner abbilden. Ändern sich die Bezeichnungen im Backend hat dies keinen Einfluss mehr auf den Frontend-Code, solange die verwendete Semantik die gleiche bleibt. Teams können sich darauf konzentrieren, über die fachliche Bedeutung der Daten zu sprechen, die sie austauschen wollen. Sie müssen nicht mehr über einzelne Bezeichner oder bestimmte Notationen wie „Camel- vs. Snake-Case“ diskutieren. Änderungen auf dieser Ebene führen nicht mehr zu Problemen. Stattdessen können sich die Teams auf die fachlich wichtige Semantik des Datenaustauschs konzentrieren.

Um JSON-LD und das beschriebene Beispiel in Aktion sehen zu können, habe ich ein JSFiddle vorbereitet:

Darüber hinaus bietet sich der JSON-LD-Playground für tiefergehende Experimente an.

Ich habe gezeigt, wie du mithilfe von JSON-LD die Bezeichner von Frontend und Backend entkoppeln kannst. JSON-LD bietet jedoch noch vieles mehr! Im nächsten Artikel werden wir weitere Daten vom Backend laden, ohne dass im Frontend „API-Endpunkte“ festgelegt sind.

Weiter mit „JSON-LD: Verlinkte Daten statt hart-kodierter Endpunkte“

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.

Kommentare

  • Björn Winkler

    7. Juli 2018 von Björn Winkler

    … bleibt die Frage, warum ich für die Kommunikation mit dem Backend einen zusätzlichen Layer einfügen muss, um zu erreichen, >> nicht mehr über einzelne Bezeichner oder bestimmte Notationen wie „Camel- vs. Snake-Case“ diskutieren << zu müssen, statt einfach gleich die durch https://schema.org/ definierten (standardisierten?) Bezeichnungen zu verwenden.

    • Angelo Veltens

      9. Juli 2018 von Angelo Veltens

      Natürlich kann man sich in einfach gelagerten Fällen auch auf Bezeichner wie „givenName“ einigen, dann ist man jedoch auf beiden Seiten wieder genau an diese Bezeichner gebunden und darf sie nicht mehr ändern.

      Weiterhin ist schema.org nur eine von vielen Ontologien im Web, die ich mit JSON-LD verwenden kann. Genannt sei z.B. GoodRelations im e-commerce Bereich.

      Die große Stärke von JSON-LD liegt jedoch darin, dass es ein Linked-Data Format ist und ich unabhängig von konkreter JSON-Serialisierung werde. Es folgen noch Artikel die dies vertiefen.

  • Björn Winkler

    9. Juli 2018 von Björn Winkler

    >>>
    Es folgen noch Artikel die dies vertiefen.
    <<<

    … ich bin gespannt!
    🙂

Kommentieren

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