Sonntag, 28. Oktober 2018

VFP, das Web und der ganze ReST - 5 - Die Startvorbereitungen / VFP, the web and all the ReST - 5 - preparations for launch

5 - Die Startvorbereitungen / preparations for launch

Einige Abkürzungen haben wir schon kennengelernt (SOAP, WDSL, ReST, JSON). Nun geht es damit munter weiter 😊. Web-basierender Datenaustausch baut in unserem Fall auf dem Hypertext Transfer Protocol kurz HTTP auf. Dieses Jahrzehnte alte Protokoll wurde in den letzten Jahren von einer sichereren Version seiner selbst ersetzt, dem Hypertext Transfer Protocol secure (=HTTPs). Mittlerweile lassen einige Browser den Zugriff auf 'unsichere' Webseiten (=HTTP) gar nicht mehr zu.

Natürlich nutzen auch Webseiten die ReST basierende Kommunikation. Dort kommt sie immer dann zum Einsatz, wenn gezielt nur einzelne Teile einer Webseite mit neuem Inhalt versehen werden sollen. Im Web ist dann von AJaX (Asynchronous JavaScript and XML) die Rede und ermöglicht den gezielten Austausch bzw. die Aktualisierung von Teilen einer Webseite ohne diese in Gänze vom Server neu abzurufen. In diesem Fall müsste ich eigentlich von AJaJ (Asynchronous JavaScript and JSON) schreiben 😊.

ReST nutzt zur Kommunikation beide Protokolle, also sowohl HTTP als auch HTTPS. Welche Variante zum Einsatz kommt hängt davon ab, welchen Modus wir innerhalb der URI (Uniform Resource Identifier) vorgeben müssen.

Um eine HTTP basierende Kommunikation aufzubauen setzen wir das Microsoft.XMLHTTP Objekt ein.

loXmlHttp = CREATEOBJECT( [Microsoft.XMLHTTP] )

Dieses Objekt verfügt über mehrere Methoden, auf die wir im weiteren Verlauf zugreifen werden.
Stellen wir also im ersten Schritt die URI zusammen.

Je nachdem wie viele unterschiedliche Webservices wir ansprechen ist es sinnvoll die Zugriffsinformationen in einer Tabelle zu speichern. Die Erfahrung lehrt uns, dass allein schon der Glaube in Zukunft keine weiteren Webservices mehr ansprechen zu müssen die Wahrscheinlichkeit darauf um mehrere 100 Prozent erhöht. In Fachkreisen wird dann üblicherweise ganz lapidar von 'Murphy’s Gesetz' gesprochen.

"Wenn es mehrere Möglichkeiten gibt, eine Aufgabe zu erledigen, und eine davon in einer Katastrophe endet oder sonst wie unerwünschte Konsequenzen nach sich zieht, dann wird es jemand genauso machen."
Edward A. Murphy, 1949
Also packen wir die notwendigen Zugriffsinformationen besser von Anfang an in eine Tabelle 😊.

Der folgende Codeblock zeigt das Zusammenbauen der URI:

*// the following values usually are part of
*// an INI file or a DB table
lcServer    = <<InsertIPadress>>
lcSubPath   = <<InsertWebPath>>
lcDienst    = <<InsertNameOfService>>

*// V E R S I O N #1
*// Based on regular URI parameters
TEXT TO lcHttpPost TEXTMERGE NOSHOW PRETEXT 1+2+4+8
    https://<<lcServer>>/<<lcSubPath>>/<<lcDienst>>
    ?param1=<<WertParam1>>
    &param2=<<URIConverter( WertParam2 , [%] )>>
ENDTEXT

*// V E R S I O N #2
*// URI parameter containing a JSON object
TEXT TO lcHttpPost TEXTMERGE NOSHOW PRETEXT 1+2+4+8
    https://<<lcServer>>/<<lcSubPath>>/<<lcDienst>>
    ?parameter=<<URIConverter( vJSON , [&] )>>
ENDTEXT 

*// take care to remove blanks from your URI
*// as well as all other irregular characters
*// before sending your URI to the xmlhttp object
*// example: BLANK -> %20
*// more about this: see previous chapter: BLANKS and other entities
*// at this point we only have to take care for still existing blanks
*// that shouldn’t be part of our URI string
lcHttpPost = STRTRAN( lcHttpPost , [ ] , [] )

Wie an den beiden Beispielen (V E R S I O N #1/#2) unschwer zu erkennen ist gibt es mehrere Ansätze per HTTP Daten an einen Webservice zu übermitteln.  Die auch heute noch recht häufig zum Einsatz kommende Variante des XML Datenstroms lasse ich aufgrund ihrer Komplexität und hochgradigen Individualität und dem aus meiner Sicht unnötigen Daten-Overhead gezielt außen vor.
Im zweiten Schritt teilen wir dem XmlHttp Objekt nun mit, wie der Service angesprochen werden soll. Zu diesem Zweck geben wir der Methode OPEN() unter anderem die gemäß Spezifikation des Dienstes zusammengestellte URI (Parameter 2) vor. Zuvor definieren wir die Kommunikationsmethode (Parameter 1) und ob die Kommunikation synchron (.F.) oder asynchron (.T.) stattfinden soll (Parameter 3).

*// "OPEN" defines the method, the data that shall be transmitted and the comm mode
*//
*// Param#1 = The method we want to use
*//           the POST method is more robust than GET and has no data limitations
*//
*// Param#2 = the webservice URI that shall be connected
*//
*// Param#3 = defines an asynchronous(.T.) or synchronous(.F.) communication
*//           As we want to wait for the webservices response, we need a 
*//           synchronous communication

oXmlHttp.open( [POST] , lcHttpString , .F. )

Anstelle von POST kann auch mit GET gearbeitet werden. Nach diversen Recherchen habe ich mich auf POST eingeschossen, da es angeblich robuster ist und keine Datenbeschränkung kennt.

Mit der Methode SEND() starten wir dann die Kommunikation

*// Now that our object has all information it needs to contact the service
*// we can grant the authorisation to start the process
oXmlHttp.send()


und warten auf das Ergebnis...


Links zu den restlichen Kapiteln:

Einführung / Introduction 

Teil 1: Abkürzungen und was sie bedeuten
           / Abbreviations and their meaning

Teil 2: Wer ReST sagt, sagt auch JSON
          / In for a ReST, in for a JSON

Teil 3: Leerzeichen und andere Entitäten
          / BLANKS and other entities

Teil 4: JSON und der goldene Konverter
          / JSON and the golden converter

Teil 5: Die Startvorbereitungen
          / preparations for launch

Teil 6: Kleine Denkpause gefällig?
          / in need of a reflection period?

Teil 7: Fertig machen zur Landung
          / preparing for landing

Keine Kommentare:

Kommentar veröffentlichen