Dynamisches Extrahieren von REST/JSON nach MySQL mit Pentaho Data Integration 7.0

Ein Tutorial

Dieses Tutorial zeigt Schritt für Schritt, wie mithilfe von Pentaho Data Integration (PDI) Daten von einer REST-Schnittstelle abgezogen und weiterverarbeitet werden können.

Darstellung eines Tunnels mittels Daten

Im Rahmen der Arbeit mit Pentaho Data Integration stellt sich einem möglicherweise die Aufgabe, nicht nur Datenbanken als Datenquelle anzubinden, sondern Daten direkt von Quellen im Internet abzuziehen. Für diesen Zweck stellt Pentaho Data Integration eine Reihe von Werkzeuge bereit, welche in einer Transformation eingebunden werden können und ohne weiteren manuellen Aufwand diese Arbeiten erledigen. Entgegen den üblicherweise verwendeten Werkzeugen gibt es jedoch nur wenige ausgetretene Pfade und ein Entwickler wird feststellen, dass diese Werkzeuge nicht intuitiv bedienbar sind.

Im Folgenden gehen wir Schritt für Schritt diese Werkzeuge und deren Implementierung durch. Zuvor betrachten wir kurz einige Begrifflichkeiten: In Pentaho Data Integration, kurz PDI, werden Transformationen erstellt. In einer Transformation befindet sich jeweils eine Aneinander-Kettung von Arbeitsschritten, welche im weiteren als Knoten bezeichnet werden. Es gibt zahlreiche Knoten in Pentaho Data Integration – einige dienen dabei als Datenquelle, andere dienen wiederum dazu die Daten in verschiedene Ziele zu schreiben. Zudem gibt es, beispielweise, Knoten, die sich mit dem Ablauf der Steuerung befassen und Knoten, die zum Transformieren, Sortieren oder Bearbeiten von Daten verwendet werden können.

Als Ergebnis und Resultat dieses Tutorials erhalten wir eine Transformation, die wie folgt aufgebaut ist:

Aufbau der fertigen Transformation mittels Pentaho Data Integration

Ausgangssituation

Es sollen Team-Daten und Details zu ausgetragenen Spielen einer Sportmannschaft von einer REST-Schnittstelle abgerufen werden. Die Daten werden dabei im JSON-Format zurückgeliefert. Im Anschluss werden diese in eine Tabelle geschrieben.

Wir verwenden hierfür Pentaho Data Integration in der Version 7.0.

Die URL zum Aufruf der REST-Schnittstelle kann dabei aus verschiedenen Paremeter bestehen, die dynamisch ermittelt und der REST-Schnittstelle als Parameter übergeben werden müssen. Der REST-Aufruf muss also dynamisch generiert werden. Ebenfalls müssen die Daten nachbearbeitet werden, da diese im JSON-Objekt nicht in tabellarischer Form vorliegen. Es sind somit folgende Schritte durchzuführen:

  1. Dynamisches Generieren der URL
  2. Laden der Daten von der REST-Schnittstelle
  3. Extrahieren der JSON-Daten
  4. Verarbeitung der geladenen Daten

1. Dynamisches Generieren der URL mit Pentaho Data Integration (PDI)

Für unser Beispiel gibt es zwei relevante URLs der REST-Schnittstelle:

  1. Einerseits jene bei der die Mannschaftsdetails aufgelistet wird, und
  2. andererseits wird ebenso die URL, die die Details (z. B. Spielergebnis, Spielort) zu Spielen der Mannschaft liefert, benötigt.

Diese zwei URLs unterscheiden sich insofern, dass die erste URL fix definiert ist und keine bestimmten Parameter benötigt. Die zweite URL (zur Abfrage der Spieldetails der Mannschaft) benötigt jedoch eine Spiel-ID als Parameter. Die Spiel-IDs sind im vorhinein jedoch nicht bekannt – diese erhält man als Ergebnis des ersten REST-Aufrufs. Dazu muss die URL für den zweiten REST-Aufruf also dynamisch ermittelt werden.

Für den REST-Aufruf der fix definierten URL verwenden wir zunächst als Start-Knoten „Generate Rows“ um genau eine Zeile zu generieren. Entweder als Teil von „Generate Rows“ oder über den Knoten „Add constant values“ fügen wir nun die URL für den REST-Aufruf hinzu. Für die erste Variante der URL wird diese mit einem fixen Wert eingetragen.

Darstellung erste URL Variante mit fixem Wert

Im Rahmen der zweiten Variante, bei der die Spiel-ID als URL-Parameter mitübergeben werden muss, wird diese URL gestückelt – dabei wird an genau den Stellen getrennt, an dem etwaige URL-Parameter benötigt werden.

Der Parameter wiederum kommt in unserem Beispiel aus einer weiteren Spalte, die im Datenstrom (als Ergebnis des Aufrufs des ersten REST-Calls) zugefügt wird. Mithilfe des Knotens „Concat Fields“ fügen wir die Elemente (der URL und Spiel-ID) nun zu einer fertigen URL zusammen.

Darstellung der fertigen URL mithilfe des Knotens "Contact Fields"

2. Laden der Daten von der REST-Schnittstelle mit PDI

Dazu wird der Knoten „REST Client“ verwendet, welcher als das Herzstück angesehen werden kann. Dieser lädt die Daten aus dem Internet herunter und bringt sie in den Datenstrom ein. Ergänzt man die im ersten Schritt angeführten Knoten im PDI, erhält man nun folgenden Ablauf für die fix definierte URL:

Ablauf der fix definierten URL

Der momentane Ablauf für die dynamisch generierte URL zur Ermittlung der Spiel-Details sieht wie folgt aus:

Darstellung Ablauf dynamisch generierte URL

Achtung: Der „REST Client“ wird für jede Zeile eines eingehenden Datenstromes einmal aktiv – es ist also unbedingt notwendig immer zuvor Zeilen zu generieren. Als Startknoten kann der „REST Client“ somit jedoch nicht fungieren.

In unserem Beispiel ist dies mit dem Knoten „Generate Rows“ bereits geschehen. Der REST Aufruf kann nun entweder über eine Konstante erfolgen oder auf Basis eines Feldes des eingehenden Datenstroms. Für uns kommt nur die zweite Variante in Frage. Dazu konfigurieren wir lediglich das Feld „URL Field Name“. Ebenfalls müssen wir das Ausgabefeld benennen und dessen Applikationstyp angeben(„json_result“ und Typ JSON). Der REST Knoten verwendet damit die von uns vorbereitete URL. Der nachstehende Screenshot zeigt die gewählten Einstellungen:

Screenshot mit den gewählten Einstellungen

3. Extrahieren der JSON-Daten mit PDI

Nun haben wir das JSON-Objekt im Datenstrom vorliegen, und können dessen Daten extrahieren. Dazu gibt es den „JSON Input“ Knoten. Die Bezeichnung als Input Knoten ist etwas irreführend, da dieser keineswegs als Start einer Transformation dient wie es bei andere Input Knoten häufig ist. Ein JSON Input Knoten zieht aus dem JSON Objekt im Datenstrom ein oder mehrere Felder gleicher Granularität heraus. Befinden sich im JSON Objekt Daten in unterschiedlichen Granularitätsstufen, welche alle abgezogen werden sollen, müssen mehrere „JSON Input“ Knoten parallel arbeiten und der Datenstrom über Joins wieder zusammengeführt werden.

Ergänzt man nach den beiden REST-Aufrufen die in den vorigen Schritten erstellten Knoten um den „JSON Input“-Knoten und fügt diese zusammen, erhält man folgenden Ablauf:

Darstellung des JSON Input Knoten Ablaufs

Der JSON Input Knoten liest dabei die Struktur von JSON anhand der Vorgabe durch einen sogenannten JSON-Path aus. Dieser muss manuell von Hand eingefügt werden, spezifisch für das zu lesende JSON-Objekt. Im Folgenden wird beschrieben, wie ein einfacher JSON-Path zusammengesetzt ist.

Beispiel: $.data.Field[*].id

Ein JSON-Path beginnt immer mit einem Dollarzeichen. Dies steht für den Anfang des Pfades. Durch Punkte getrennt folgen Bezeichnungen für den Pfad. Hier zuerst „data“ dann „Field“ und zuletzt „id“. Dieser Pfad beinhaltet darüber hinaus eine Liste, für eine List werden die Zeichen [*] im Pfad inkludiert.

Darstellung einer Liste, in der der JSON Input Knoten im Durchlauf eine eigene Zeile für jeden Eintrag erstellt

Der JSON Input Knoten erstellt im Durchlauf eine eigene Zeile für jeden Eintrag in der Liste. Bei einem einzenen REST Aufruf ist das Resultat noch eine einzelne Zeile. Nach dem JSON Input Knoten ist es möglich, dass hier zahlreiche Zeilen ausgegeben werden.

4. Verarbeitung der geladenen Daten mit PDI

Als abschließende Schritte empfehlen wir mit dem „Select Values“ Knoten nur die relevanten Felder im Datenstrom beizubehalten und z.B. die URL und das JSON Objekt zu verwerfen. Mit einem „Sort“-Knoten könnten die Daten zudem in eine angenehm lesbare Reihenfolge gebracht werden.

Abschließend schreiben wir die Daten nun in eine Datenbank. Dazu werden wir in diesem Beispiel den „Table output“ Knoten und verbinden ihn mit einer MySQL-Datenbank. Sofern die Zieltabelle vorhanden ist, ist damit der gesamte Prozess erfolgreich abgeschlossen.

Zusammenfassung

Als Ergebnis erhalten wir nun eine Transformation, die wie folgt aussieht:

Aufbau der fertigen Transformation mittels Pentaho Data Integration

Die Anforderungen sind dadurch erfüllt – wir rufen die REST-Schnittstelle einer fixen URL für die Mannschafts-Details auf. Dabei erhalten wir ein JSON-Objekt, welches eine ID für Spiel-Details enthält. In weiterer Folge wird durch die zuvor ausgelesene Spiel-ID die URL (der Spieldetails) für einen erneuten REST-Aufruf ermittelt. Das wiederum erhaltene JSON-Objekt wird ausgelesen und die Daten stehen zu unserer Verfügung.

Wir konnten somit zeigen, wie man sich mithilfe von Pentaho Data Integration 7 JSON-Daten einer REST-Schnittstelle abgreift, und diese in eine Tabelle schreibt.