REST API Anbindung mit Synesty
Einleitung
In diesem Tutorial lernen Sie Schritt für Schritt, wie man mit Synesty Basis-Bausteinen eine individuelle REST-API mit JSON als Datenaustauschformat anbinden kann.
Synesty verfügt über Bordmittel (Steps), mit denen Sie in der Lage sind jeder beliebige REST-API per HTTP anzubinden. Das heißt, dass Sie nicht abhängig von den Add-Ons sind, die Synesty bereitstellt, sondern auch völlig andere APIs individuell anbinden können.
Bordmittel
Die wichtigen Steps für eine API-Anbindung sind:
- APICall
- SpreadsheetURLDownload
- JSONReader
- optional: XMLReader (optional deshalb, weil der Step in diesem Beispiel nicht vorkommt, aber bei XML-APIs statt JSONReader genutzt werden könnte)
Unterschied zwischen APICall, SpreadsheetURLDownload und URLDownload
Dieses Cookbook beschreibt den Unterschied der drei Steps.
Beispiel API
Für die Beispiele nutzen wir den Service von https://my-json-server.typicode.com/, der es erlaubt eine REST-API zu simulieren. Das ist notwendig, da die REST-APIs
der meisten Systeme umfangreichere Voraussetzungen und Einrichtung benötigen, bevor man diese benutzen kann. Das wäre für so ein Tutorial nicht hilfreich. Deshalb bauen wir auf die Beispiele von https://my-json-server.typicode.com/typicode/demo , die ein Blog mit Artikeln (Posts) und Kommentaren (Comments) simulieren.
API Calls testen
Zum Ausprobieren der obigen Beispiele ohne Synesty Studio empfehlen wir Ihnen ein Tool wie z.B. den
ARC (Advanced REST Client) https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=de
oder POSTMAN (https://www.getpostman.com/)
1. GET Request
Der einfachste Fall ist ein sog. HTTP GET Request.
https://my-json-server.typicode.com/typicode/demo/posts
Diese URL gibt eine Liste von Artikeln (sog. Posts) zurück:
Antwort der REST-API
[
{
"id": 1,
"title": "Post 1"
},
{
"id": 2,
"title": "Post 2"
},
{
"id": 3,
"title": "Post 3"
}
]
1.1. Einzelnen Artikel mit GET abrufen
Um die Daten eines einzelnen Artikels abzurufen, können Sie folgende URL verwenden:
https://my-json-server.typicode.com/typicode/demo/posts/1
Diese URL ruft den Artikel mit der ID=1 ab.
Antwort der REST-API
{
"id": 1,
"title": "Post 1"
}
In diesem Fall bekommen wir einen einzelnen Artikel, statt einer Liste.
2. POST Request
Ein HTTP-POST Request wird meistens genutzt, um Objekte neu zu erstellen oder zu modifizieren.
Bei einem POST-Request übergibt man eine JSON-Payload, mit dem Objekt, welches angelegt werden soll.
In der Literatur findet man auch PUT zum Erstellen, wobei die Meinungen darüber sehr stark variieren, siehe https://stackoverflow.com/questions/630453/put-vs-post-in-rest
Bezogen auf das Beispiel mit den Artikeln, könnte man mit folgendem POST Request einen neuen Artikel anlegen.
Der Artikel besteht aus Titel, Text, Kategorie und einem Flag für Sichtbarkeit:
Request
{
title: "my first post" ,
text: "this is my first text",
category: 1,
visible: true
}
Die Antwort des Servers ist wiederum ein JSON, der die ID des neu angelegten Artikels beinhaltet.
Antwort der REST-API
{
"id": 4
}
3. Beispiele mit Synesty Studio umsetzen
In diesem Abschnitt wollen wir nun die obigen Beispiele mit Synesty Studio umsetzen.
3.1. GET Request mit Einlesen der Antwort
Dazu benutzen wir den APICall Step.
Damit können wir den GET Request absetzen und auch die Antwort mit dem *parsingTemplate *einlesen und in ein Spreadsheet umwandeln.
die wichtigste Zeile im *parsingTemplate ist addColumns().
Parameter | Wert | Beschreibung |
---|---|---|
host | die URL des GET Request | |
method | GET | |
responseFormat | JSON | Damit sagen wir, dass die Antwort im JSON Format zurück kommt. |
parsingTemplate | Parsing Script für REST-API Antwort
| Hiermit wird die Antwort eingelesen. Die Variable json ist ein Platzhalter des Steps, der das JSON-Objekt repräsentiert. Die <#list> Anweisung iteriert über jedes Objekt des Arrays. Mit der alias-Variable j greifen Sie auf auf das einzelne Objekt (Array-Element) zu. Die addColumns() Funktion fügt nun alle Felder des JSON-Objekts j der Zeile row hinzu. |
Beispiel Video:
3.2. Mehrere GET Requests basierend auf einem Spreadsheet ausführen
Das nächste Beispiel geht davon aus, dass man eine eine Liste mit Artikel-IDs hat und pro Artikel-ID die Informationen abrufen will.
Die besagte Liste kommt aus einer CSV-Datei, die in ein Spreadsheet eingelesen wird.
articles.csv
artikelID
1
3
Diese CSV Datei ist sehr simpel und besteht nur aus einer Spalte. Darin enthalten sind 2 Artikel-IDs 1 und 3.
Ziel: Pro Zeile soll ein GET-Request ausgeführt werden, jeweils für die entsprechende Artikel-ID.
D.h. wir erwarten folgende 2 GET-Requests:
https://my-json-server.typicode.com/typicode/demo/posts/1
https://my-json-server.typicode.com/typicode/demo/posts/3
Dazu verwenden wir den Step SpreadsheetURLDownload, da dieser Step pro Spreadsheet-Zeile einen Request ausführen kann.
StringToFile
Hiermit erzeugen wir die Test-CSV-Datei.
CSVReader
Damit wird die CSV-Datei in ein Spreadsheet eingelesen.
SpreadsheetURLDownload
Step-Vorschau:
Da der SpreadsheetURLDownload Step keine JSON-Parsing Möglichkeit bietet (im Gegensatz zum APICall) verwenden wir den JSONReader Step, um die einzelnen JSON-Antworten zu verarbeiten. Der JSONReader kann mit mehreren Inputs umgehen, d.h. in diesem Fall liegen 2 JSON-Antworten in der responseContent Spalte vor (da ja 2 GET-Requests gemacht wurden... ein Request pro Artikel).
Beispiel Video:
3.2. Einzelner POST Request
Aufbauend auf dem Szenario 3.1. wollen wir nun einen einzelnen POST Request ausführen um z.B. einen neuen Artikel zu erstellen. Die Antwort wollen wir auch wieder einlesen, um Sie weiterverarbeiten zu können.
Dazu benutzen wir wieder APICall Step, da es sich um einen einzelnen Request handelt.
Parameter | Wert | Beschreibung |
---|---|---|
host | die URL des GET Request | |
method | POST | |
requestBody | Request
| Das (Phantasie)-JSON-Objekt für einen neuen Artikel. |
responseFormat | JSON | Damit sagen wir, dass die Antwort im JSON Format zurück kommt. |
parsingTemplate | Parsing Script für REST-API Antwort
| Hiermit wird die Antwort eingelesen. Die Variable json ist ein Platzhalter des Steps, der das JSON-Objekt repräsentiert. Die <#list> Anweisung iteriert über jedes Objekt des Arrays. Mit der alias-Variable j greifen Sie auf auf das einzelne Objekt (Array-Element) zu. Die addColumns() Funktion fügt nun alle Felder des JSON-Objekts j der Zeile row hinzu. |
requestHeaders |
| Das kann sich je nach REST-API unterscheiden. Unsere Test-API braucht Content-type=text/json, ansonsten liefert der Server ein 500 Internal server error. |
Das POST-Beispiel ist nahezu identisch mit dem GET-Beispiel. Der Unterschied ist der requestBody, der bei POST definiert werden kann.
Tutorial zum Them JSON erstellen
Unser Tutorial zeigt, wie Sie mit ${toJSON()}
und ${newMap()}
zuverlässig valides JSON erstellen, das Sie im requestBody an die API übermitteln.
3.3. Mehrere POST Requests
Praktisch relevanter ist ein Beispiel, in dem mehrere POST ausführt, um z.B. mehrere Artikel anzulegen oder zu aktualisieren.
Wir setzen hier wieder auf das vorangegangene Beispiel mit mehreren GET-Requests auf und adaptieren es für POST.
Dazu ändern wir unsere CSV-Datei etwas ab, mit Feldern aus dem Einzel-POST-Request Beispiel:
articles.csv
title;text;category;visible
"my first post";"this is my first text";"1";"true"
"my second post";"this is my second text";"2";"false"
Ziel: Pro Zeile soll ein POST-Request ausgeführt werden und jeweils ein neuer Artikel mit den jeweiligen Daten (title, text, category, visible) erzeugt werden.
D.h. wir erwarten folgende 2 POST-Requests:
Request 1
POST https://my-json-server.typicode.com/typicode/demo/posts/
{
title: "my first post" ,
text: "this is my first text",
category: 1,
visible: true
}
Request 2
POST https://my-json-server.typicode.com/typicode/demo/posts/
{
title: "my second post" ,
text: "this is my second text",
category: 1,
visible: true
}
Dazu verwenden wir wieder den Step SpreadsheetUrlDownload, da dieser Step pro Spreadsheet-Zeile einen Request ausführen kann.
Dieses mal allerdings mit POST (statt GET) und einem dynamischen requestBody mit den Daten aus der CSV-Datei.
Dynamischer requestBody
Im requestBody verwenden wir Variablen, die durch den Spaltenwert der jeweiligen Input-Spreadsheet-Zeile ersetzt wird:
Request mit Platzhalter-Variablen
{
title: "${title!}" ,
text: "${text!}",
category: ${category!},
visible: ${visible!}
}
Die verwendeten Platzhalter-Variablen werden bei der Ausführung durch den Spalten-Wert aus der Spreadsheet-Zeile ersetzt - d.h. in der ersten Zeile wird ${title!} zu "my first post", in der zweiten wird *${title!} *zu *"my second post" *usw.
Der Screenshot des SpreadsheetURLDownload zeigt das ebenfalls nochmal.
Infos zu Platzhalter-Variablen
Merke: Die Platzhalter funktionieren nicht nur im requestBody sondern auch in host oder requestHeaders. D.h. auch die URL oder die HTTP-Header kann man dynamisch aus den Spalten-Inhalten zusammenbauen.*
*Immer den +-Button an den Feldern verwenden! Damit erhält man die verfügbaren Platzhalter-Variablen.
Ungültige JSON-Zeichen aus Platzhaltern entfernen
Wenn man im requestBody eine JSON-Payload zusammenbaut, dann kann es vorkommen, dass im Wert eines Platzhalters Zeichen vorkommen, die in JSON aber nicht erlaubt sind bzw. erst "escaped" werden müssen. D.h. die Gegenseite (API) würde den Request vermutlich mit einer Fehlermeldung ablehnen (z.B. "Bad Request").
Um das zu vermeiden, sollten Sie bei Text-Variablen das ?json_string Built-In von Freemarker verwenden.
D.h. der obige requestBody, sollte wie folgt umformuliert werden, damit man auf der sicheren Seite ist:
Request mit Platzhalter-Variablen und Escaping
{
title: "${title!?json_string}" ,
text: "${text!?json_string}",
category: ${category!},
visible: ${visible!}
}
Warum kein ?json_string bei category und visible?
In unserem Beispiel ist category immer eine Zahl und visible immer true oder false. D.h. wir wissen, dass da niemals ungültige JSON-Zeichen drin stehen. ?json_string ist immer bei langen Strings sinnvoll wie z.B. product_description.
Step | Konfiguration | Beschreibung |
---|---|---|
StringToFile | Hiermit erzeugen wir die Test-CSV-Datei. | |
CSVReader | Step-Vorschau: | Damit wird die CSV-Datei in ein Spreadsheet eingelesen. |
SpreadsheetURLDownload | Step Vorschau: Hier sieht man, dass 2 POST Requests gesendet wurden, mit 2 unterschiedlichen JSON-Objekten... jeweils mit den Werten aus der CSV-Datei. Hinweis: Nicht wundern. in responseContent taucht zwei mal id=4 auf. Das liegt an der Test-REST-API, die immer die gleiche Antwort liefert, da in Wirklichkeit kein neuer Artikel angelegt wird. | Hiermit wird wir pro ArtikelID ein GET-Request gemacht. Den outputMode sollten Sie auf "Add response content to output spreadsheet" setzen, damit die JSON-Response auch in der Vorschau der Antwort auftaucht. Das Ergebnis des Steps ist ein Spreadsheet mit verschiedenen Dingen aus der HTTP-Response und u.a. der Spalte responseContent, die den für uns interessanten JSON-Inhalt beinhaltet. |
JSONReader | Step Vorschau: Da die JSON-Response nur die ID beinhaltet, erhalten wir auch nur eine Spalte im Spreadsheet. | Da der SpreadsheetURLDownload Step keine JSON-Parsing Möglichkeit bietet (im Gegensatz zum APICall) verwenden wir den JSONReader Step, um die einzelnen JSON-Antworten zu verarbeiten. Der JSONReader kann mit mehreren Inputs umgehen, d.h. in diesem Fall liegen 2 JSON-Antworten in der responseContent Spalte vor (da ja 2 GET-Requests gemacht wurden... ein Request pro Artikel). |
Beispiel Video:
Dieses Video zeigt den wichtigen Teil, wo der JSON-Request aus den Daten der CSV-Datei zusammengebaut wird. Dabei wird zuerst das statische JSON-Beispiel genommen und sukzessive durch die Variablen ersetzt.
Komplettes Projekt zum Nachstellen
Das hier gezeigte Projekt steht als Vorlage zur Verfügung und kann in Ihrem Account installiert werden.