Der HTTP-Provider ermöglicht es HTTP-Schnittstellen in YUNA-Dashboards zu integrieren und somit Daten von externen Services in Dashboards einzubinden oder umgekehrt die Daten aus einem Dashboard an diese zu senden.
Mit Hilfe von Handlebar-Templates können die HTTP-Anfragen dynamisch konfiguriert werden.
Beispielgrafik: Versenden von Formulardaten an eine HTTP-Schnittstelle mit Hilfe des HTTP-Provider:
- Bei Betätigung des Absenden-Buttons im Formularwidget werden die eingegebenen Daten an den Output-Channel des Formularwidgets übergeben.
- Die durch den IO-Channel bereitgestellten Daten werden durch den HTTP-Provider konsumiert, da dieser IO-Channel als Input konfiguriert ist.
- Der HTTP-Provider führt ein mit den bereitgestellten Daten angereichertes Request durch.
- Die angefragte HTTP-Schnittstelle liefert eine Antwort an den HTTP-Provider.
- Die Antwort wird in den Response-Output-Channel des HTTP-Providers übergeben. Der Body der Antwort wird entsprechend der Konfiguration des HTTP-Providers ausgelesen.
- Das Formularwidget erhält die neuen Daten aus dem IO-Channel und kann diese darstellen.
Beispielkonfigurationen für HTTP-Provider:
Durch klick auf die verschiedenen YUNAML-Elemente gelangen sie zu den jewiligen detaillierten Informationen in den folgenden Tabelle.
Konfiguration des HTTP-Providers
YUNAML-Tag | Beschreibung | Konfiguration erforderlich? | Beispiel |
---|---|---|---|
type | Der Typ des IO-Providers. Für den HTTP-Provider muss dieser Parameter auf "HTTP" gesetzt werden. Weitere mögliche Werte sind "UrlParams" und "DataID". | <type>HTTP<http> | |
config | Die verschiedenen Konfigurationsparameter des HTTP-Providers. Die Konfiguration lässt sich für das leichtere Verständnis in zwei Teile zerlegen:
|
Konfiguration der In- und Output-Channels
YUNAML-Tag | Beschreibung | Konfiguration erforderlich? | Beispiel | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
config > inputs | Die Input-Channel des HTTP-Providers. Die konfigurierten Channel werden für zwei Zwecke verwendet:
Um den Zeitpunkt für die Anfrage zu konfigurieren, werden die Input-Channel in drei YUNAML-Tags definiert: <trigger>, <mandatory> und <optional>. Bei jeder Änderung eines Channels, der in mindestens einem dieser Tags definiert ist, wird geprüft, ob eine Anfrage durchgeführt werden soll. Dabei werden folgende Bedingungen geprüft:
Sind weder <trigger>- noch <mandatory>-Channel definiert, wird bei jeder Änderung eines in <optional> angegebenen Kanals eine Anfrage ausgeführt. Ein Channel kann sowohl <trigger> als auch <mandatory> sein. Sollen mehrere Channel in einem der drei Tags definiert werden, müssen diese in <list>-Tags angegeben werden. | <inputs> <trigger>someChannel</trigger> <mandatory> <list>dataChannel</list> </mandatory> <optional> <list>OptionalChannel2</list> <list>InputChannel2</list> </optional> </inputs> | ||||||||||||||||
config > inputs > trigger | ||||||||||||||||||
config > inputs > mandatory | ||||||||||||||||||
config > inputs > optional | ||||||||||||||||||
config > outputs | Unter <outputs> wird konfiguriert, in welche IO-Channel die gesendete Anfrage und die Antwort der abgefragten Schnittstelle veröffentlicht werden. Das Format, in dem die Daten veröffentlicht werden, kann über <requestBodyAs> und <responseBodyAs> konfiguriert werden. | <outputs> <request>OutputChannelName1</request> <response>OutputChannelName2</response> </outputs> | ||||||||||||||||
config > outputs > request | Der <request>-Channel wird genutzt um den abgesendeten Request zu veröffentlichen. Dabei wird der Body der Anfrage entsprechend der Konfiguration in <requestBodyAs> konvertiert. Das in den angegebenen Channel veröffentlichte Objekt hat unter anderem folgende Eigenschaften:
| |||||||||||||||||
config > outputs > response | Der <response>-Channel wird mit der Antwort der angefragten HTTP-Schnittstelle befüllt. Dabei wird der Body der Anfrage entsprechend der Konfiguration in <responseBodyAs> konvertiert. Das in den angegebenen Channel veröffentlichte Objekt hat unter anderem folgende Eigenschaften:
| |||||||||||||||||
config > requestBodyAs | Der Datentyp, in dem der Body des Requests bzw. der Response erwartet wird. Der HTTP-Provider versucht den Body entsprechend der Konfiguration zu konvertieren. Unterstützte Datentypen:
Für weitere Details zu den verschiedenen Datentypen und ihren Verwendungszwecken, finden die in der MDN-Dokumentation des Body mixin. | <requestBodyAs>json</requestBodyAs> | ||||||||||||||||
config > responseBodyAs | <responseBodyAs>json</responseBodyAs> |
Konfiguration der HTTP-Anfrage
Die über den HTTP-Provider zu sendende Anfrage kann über mehrere YUNAML-Tags konfiguriert werden. Diese sind in untenstehender Tabelle erläutert.
Die Inhalte aller YUNAML-Tags in diesem Block können mithilfe von Handlebar-Templates dynamisch gesetzt werden. Dabei werden die Daten aus den <input>-Channels verwendet, um die Platzhalter in den Handlebar-Templates zu befüllen.
YUNAML-Tag | Beschreibung | Konfiguration erforderlich? | Beispiel |
---|---|---|---|
config > method | Die HTTP-Methode, die für die Anfrage verwendet werden soll. Häufig genutzte Methoden: GET, POST, PUT, DELETE |
| |
config > url | Die Adresse, an die die Anfrage gestellt werden soll. Dies kann entweder eine absolute URL sein, also zum Beispiel mit "https://" beginnen, oder relativ, wenn eine YUNA-REST-Schnittstelle abgefragt werden soll. URL-Parameter können entweder direkt in dem Template angegebem werden, oder über die Einträge im Tag <urlParameters> hinzugefügt werden. | <url>https://jsonplaceholder.typicode.com/posts/{{formChannel.[1].number}}</url> | |
config > urlParameters | URL-Parameter, die an die URL angehängt werden sollen. Die Angabe erfolgt in XML-Notation. Der Tag definiert den Namen des Headers, der Inhalt den Wert. | <urlParameters> <parameterName>parameterValue</parameterName> </urlParameters> | |
config > body | Der Body, der mit der Anfrage versendet werden soll.
Der Body kann mit Handlebar-Templates dynamisch konfiguriert werden. | <body> { "staticTextField": "Hello ", "fieldFromTemplate": "{{inputChannel.name}}" } </body> | |
config > headers | Header, die für die Anfrage verwendet werden sollen. Im <headers>-Tag werden die Namen der Header in Tags angegeben und die jeweiligen Werte als Inhalt des Tags. Schematisch: | <headers> <keep-alive>{{paramChannel.keepAlive}}</keep-alive> </headers> | |
config > unsafeCredentialDelegation | Erlaubte Werte: true | false (Standard = Abgeschaltet) Aktiviert bei einem CORS-Request die automatische Anmeldung des Browsers bei dem Zielserver des HTTP-Request, falls möglich. Standardmäßig verbietet eine Browserrichtlinie die automatische Anmeldung bei einem CORS-Request. Weitere Browser-, Netzwerk-, Sicherheits- oder Systemrichtlinien können den CORS-Request sowie die automatische Anmeldung bei dem Zielserver verhindern. Der verwendete Browser muss möglicherweise für die automatische Anmeldung konfiguriert werden. Ist diese Option aktiviert werden Informationen für eine Benutzeranmeldung (Cookies, Nutzername, Passwort, usw.) an den Zielserver gesendet. Der Zielserver muss folgende Header setzen, damit diese Option genutzt werden kann:
| <unsafeCredentialDelegation>false</unsafeCredentialDelegation> |
Same-Origin-Policy (SOP) der Browser und Cross-Origin Resource Sharing (CORS) bei der Nutzung des HTTP-Provider
Das Abrufen von Ressourcen von anderen Servern wird durch die Same-Origin-Policy der Browser standardmäßig unterbunden.
Wenn Yuna z.B. unter der URL https://yuna.demo.dev verfügbar ist und über den HTTP-Provider ein Request an https://weather.example.dev/api/weather?q=Kassel gesendet werden soll kann dieser Request vom Browser unterbunden werden, da es sich nicht um den Selben Server handelt der Yuna bereitstellt. Dies ist ein Sicherheitskonzept (Same-Origin-Policy) bei der Verwendung von JavaScript im Browser. Externe APIs sind üblicherweise für den Zugriff von beliebigen anderen Servern über Cross-Origin Resource Sharing konfiguriert.
Durch die Konfiguration von Cross-Origin Resource Sharing auf dem externen Servers kann dieser den Request aus Yuna heraus erlauben.
Um den Request an den Server (hier: weather.example.dev) zu erlauben muss auf dem Server (hier: weather.example.dev) der CORS Header konfiguriert werden.
Weitere Informationen finden Sie auf der Seite enable cross-origin resource sharing.
Wie der Zielserver des Request konfigriert wird finden Sie für die entsprechende Webserver-Software (Apache, nginX, usw.) unter enable CORS.
Beispiel
In diesem Beispiel wird über den IO-Provider ein http POST-Request mit Daten aus einem Tabellen-Widget an die Adresse https://postman-echo.com/post gesendet. Die Response (Server-Antwort) wird in einem Formular-Widget dargestellt.
<xml> <!-- Copyright (c) 2019 eoda GmbH --> <view name="dpe-973" roles="System_Admin, AdHoc_Full_Issue"> <caption>DPE-973: SIS-Service-Call</caption> <description>Dashboard, das ein dem SIS-Service-Call ähnliches Beispiel abbildet</description> <userdocu>https://jira.eoda.de/browse/dpe-973</userdocu> <widget> <position> <x>0</x> <y>0</y> </position> <size> <x>12</x> <y>8</y> </size> <caption> <show>true</show> <label>form-widget</label> </caption> <widgettype>formwidget</widgettype> <inputs> <response>responseChannel</response> </inputs> <outputs> <submit>formWidgetDataWasSentChannel</submit> </outputs> <formTemplate> <![CDATA[ <div> <h2>Response:</h2> <p>selected: {{inputs.response}}</p> </div> <br> ]]> </formTemplate> <submitButton> <dataID>qy_dpe-1387</dataID> <label>GO!</label> </submitButton> </widget> <!-- Copyright (c) 2019 eoda GmbH --> <widget name="MultiChoiceSelection_Table_dpe_1387"> <position> <x>0</x> <y>9</y> </position> <size> <x>16</x> <y>7</y> </size> <widgettype>tabledirective</widgettype> <dataID>qy_dpe-1387</dataID> <sorting>ProductGroup</sorting> <sortingorder>asc</sortingorder> <outputs> <selected>selectedData</selected> </outputs> <cols> <list> <field>ProductGroup</field> <title>ProductGroup</title> <sortable>ProductGroup</sortable> <filter> <ProductGroup>text</ProductGroup> </filter> <show>true</show> <width>50</width> <style></style> </list> <list> <field>EquipmentNo</field> <title>EquipmentNo</title> <sortable>EquipmentNo</sortable> <filter> <EquipmentNo>text</EquipmentNo> </filter> <show>true</show> <width>50</width> <style></style> </list> <list> <field>ProductionCounter</field> <title>ProductionCounter</title> <type>number</type> <width>50</width> <filter> <ProductionCounter>number-custom</ProductionCounter> </filter> <show>true</show> </list> <list> <field>ParentEquipmentNo</field> <title>ParentEquipmentNo</title> <width>50</width> </list> <list> <field>EndCustomer</field> <title>EndCustomer</title> <width>50</width> </list> <list> <field>Location</field> <title>Location</title> <width>50</width> </list> <list> <field>LocationCountry</field> <title>LocationCountry</title> <width>50</width> </list> <list> <field>EquipmentFamily</field> <title>EquipmentFamily</title> <width>50</width> </list> <list> <field>MachineType</field> <title>MachineType</title> <width>50</width> </list> <list> <field>LastServiceMission</field> <title>LastServiceMission</title> <type>genDate</type> <width>50</width> <filter> <LastServiceMission>date-custom</LastServiceMission> </filter> <show>true</show> </list> </cols> <generalOptions> <selectable>true</selectable> </generalOptions> </widget> <io-provider> <type>HTTP</type> <config> <inputs> <mandatory>selectedData</mandatory> <trigger>formWidgetDataWasSentChannel</trigger> </inputs> <outputs> <response>responseChannel</response> </outputs> <method>POST</method> <url>https://cors-anywhere.herokuapp.com/https://postman-echo.com/post</url> <unsafeCredentialDelegation>false</unsafeCredentialDelegation> <body>{{json selectedData}}</body> <requestBodyAs>json</requestBodyAs> <responseBodyAs>text</responseBodyAs> <headers> <Cache-Control>no-cache</Cache-Control> </headers> </config> </io-provider> </view> </xml>