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:
- JSON-Bezeichner werden geändert.
- Die Struktur der Daten wird verändert.
- Bestimmte Daten werden nicht mehr direkt ausgeliefert, sondern erfordern eine zusätzliche HTTP-Anfrage.
- 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,
- wie du unterschiedliche JSON-Bezeichner in Backend und Frontend verwenden kannst
- wie du Daten lädst, ohne vorab im Frontend die „Endpunkte“ zu kennen
- 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:
1{ 2 "id": "42", 3 "firstname": "John", 4 "lastname": "Doe", 5 "birthday": "1978-05-17" 6}
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
:
1function greet(person) {
2 return `Hello, ${person.firstname} ${person.lastname}`;
3}
Das Backend-Team ändert nun die ausgelieferte Datenstruktur wie folgt ab:
1{ 2 "id": "42", 3 "firstName": "John", 4 "lastName": "Doe", 5 "birthday": "1978-05-17" 6}
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:
1{ 2 "@context": { 3 "@vocab": "https://schema.org/", 4 "firstname": "givenName", 5 "lastname": "familyName", 6 "birthday": "birthDate", 7 "id": "@id" 8 }, 9 "id": "42", 10 "firstname": "John", 11 "lastname": "Doe", 12 "birthday": "1978-05-17" 13}
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:
1var context = { 2 "@vocab": "https://schema.org/", 3 first_name: "givenName", 4 last_name: "familyName", 5 birth_date: "birthDate", 6 person_id: "@id" 7}
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:
1import * as jsonld from "jsonld";
2
3// Frontend-Kontext auf Backend-Daten anwenden
4jsonld.compact(context, backendData, (err, person) => {
5 greet(person);
6});
7
8function greet(person) {
9 console.log(`Hello, ${person.first_name} ${person.last_name}`);
10}
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:
1{ 2 "@context": { 3 "@vocab": "https://schema.org/", 4 "first_name": "givenName", 5 "last_name": "familyName", 6 "birth_date": "birthDate", 7 "person_id": "@id" 8 }, 9 "person_id": "42", 10 "birth_date": "1978-05-17", 11 "last_name": "Doe", 12 "first_name": "John" 13}
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“
Weitere Beiträge
von Angelo Veltens
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Angelo Veltens
Software Developer & Consultant
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.