ID-INFO-Blog

Webdienste auf dem IBM i

Sie haben höchstwahrscheinlich schon von Webdiensten gehört, aber was genau ist das?

Wenn Sie Ihre Lieblingssuchmaschine befragen, erfahren Sie, dass ein Webdienst ein Schnittstellenprotokoll ist, das es zwei Anwendungsprogrammen ermöglicht, miteinander zu diskutieren. Diese basieren auf Webtechnologien, damit zwei Anwendungsprogramme, die völlig unterschiedlich sein können, Informationen austauschen können.

Aus diesem Grund werden Webdienste häufig in verteilten Umgebungen eingesetzt, in denen viele heterogene Anwendungen miteinander kommunizieren müssen. Außerdem spiegeln diese Tools die Prinzipien der serviceorientierten Architektur (SOA) wider, die in unseren Informationssystemen immer häufiger anzutreffen sind und die es uns ermöglichen, in Bezug auf die Lösungen, die wir anbieten können, viel flexibler zu sein.

Heutzutage stützen sich Webdienste auf das Hypertext Transfer Protocol (HTPP), um Informationen zu transportieren. Die Verwendung dieses Standards hat den enormen Vorteil, dass er enorm viele Probleme bei der Konnektivität zwischen unseren beiden Anwendungen vermeidet.

Webdienste basieren auf einem Austausch vom Typ Client/Server. In der Praxis bleibt die Anwendung, die den Dienst bereitstellt (häufig wird gesagt, dass sie den Dienst exponiert), auf mögliche, von den Clients ausgelöste Anfragen hören. Die Anfrage wird vom Server interpretiert, verarbeitet und die Antwort in einer für den Client verständlichen Form an die Clientanwendung weitergeleitet.

 

Es gibt 2 große Familien von Webdiensten:

  • Die Webdienste SOAP: Simple Object Access Protocol
  • REST-Webdienste: Representational State Transfer

 

Die ersten, basieren auf dem gleichnamigen Protokoll. Die erste Version, die von Microsoft und iBM definiert wurde, ist 23 Jahre alt und wurde dann durch eine Empfehlung des W3C zum Standard. Das Protokoll stützt sich vollständig auf die XML-Sprache, um den Austausch zwischen Clients und Servern formal zu beschreiben. Dieser Formalismus (über XML-Dokumente namens WSDL) hat den Vorteil, dass er eine implizite Dokumentation bereitstellt, wenn man diese Art von Diensten nutzt. Leider hat die Familie einige Nachteile: Da die XML-Sprache besonders wortreich ist, kann die Nutzung dieser Art von Webdiensten schnell kompliziert werden. Andererseits impliziert der Formalismus, dass die Clients und der Server stark gekoppelt sind, was in einem SOA-Ansatz, in dem man immer mehr Flexibilität anstrebt, nicht unbedingt wünschenswert ist.

 

Diese Nachteile haben die Entstehung der Familie der REST-Webdienste begünstigt. Diese basieren auf den architektonischen Konzepten, die im Web verwendet werden, um entfernte Ressourcen in Textform zu manipulieren. Im Gegensatz zu SOAP-Webdiensten beschränkt sich die Familie der REST-Webdienste nicht nur auf das XML-Format, um Informationen zwischen den beiden Anwendungsprogrammen Client / Server auszutauschen: Formate wie JSON werden heute allgemein verwendet. Um entfernte Ressourcen zu manipulieren, verwenden diese Webdienste die http-Methoden : POST, GET, PUT, DELETE, … die an das CRUD-Entwicklungsmodell anknüpfen, weshalb diese Webdienste häufig verwendet werden, um komplette APIs (Application Programming Interface) zu erstellen, die mit den Elementen einer Anwendung interagieren.

 

Aber was ist mit unserem IBM i? Kann auch sie sich in diese verteilten Umgebungen einfügen?

 

Ich kann Sie gleich beruhigen, unsere Lieblingsplattform verfügt über enorm viele Tools, um Webdienste auszustellen oder zu konsumieren. Wie viele andere Plattformen können wir diese Dienste auf unterschiedliche Weise implementieren und sie unseren verschiedenen Kunden zur Verfügung stellen.

 

Um dies zu veranschaulichen, wollen wir uns in die Situation einer bestehenden Anwendung versetzen, die in RPGIV entwickelt wurde.

 

Dazu erstellen wir uns zunächst eine Umgebung mit einigen Tabellen und Daten. Zu unserem Glück hat uns IBM dafür eine SQL Stored Procedure in einer Zeile zur Verfügung gestellt:

CALL QSYS.CREATE_SQL_SAMPLE(‚RHDB‘);

 

Öffnen wir also unser Werkzeug zur Ausführung von SQL-Skripten in ACS und starten wir es.

 

Wie Sie vielleicht schon am Namen der erstellten Sammlung erraten haben, werden wir mit Daten aus dem Bereich der Humanressourcen arbeiten.

 

Ein kurzer Blick in den Datenbank-Explorer, zeigt uns die erstellten Tabellen.

 

Werfen wir einen Blick auf die Tabelle EMPLOYEE und schreiben ein kleines Programm, um Informationen über einen Mitarbeiter abzurufen.

 

Angenommen, wir haben ein Dienstprogramm, mit dem wir die Informationen über einen Mitarbeiter abrufen können.

      /if not defined(IMPORT_PROTOTYPES)         ctl-opt option ( *nodebugio : *srcstmt )           debug           nomain           pgminfo(*PCML : *MODULE);       * Parametres SQL.         exec sql           set option commit = *none,                      closqlcsr = *endmod;

      *======================================================================= *       *                                                                        *       * ATTENTION :                                                            *       *                                                                        *       * ---------------------------------------------------------------------- *       * FONCTION     : Module RH.                                              *       * DESCRIPTION  : Manipulation donénes du personnel.                      *       *                                                                        *       * Creation ... : 25/10/2021   par  L. KIEFFER (Notos-Id Info)            *       * ---------------------------------------------------------------------- *       * Modification :                                                         *       * JJ/MM/AAAA - XXXXXX XXXXXXX - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.     *       *                                                                        *
      * ---------------------------------------------------------------------- *       /endif       *----------------------------------------------------------------------       * Prototype verification sous systeme.       * ---------------------------------------------------------------------         // Information employé.         dcl-ds MODULERH_employe template qualified;            prenom varchar(12);            nom varchar(15);            service varchar(36);         end-ds;         // Recherche d'un employé.         dcl-pr MODULERH_rchEmp;           iNumEmp char( 6 ) const;           oInfEmp likeds ( MODULERH_employe );           oErrHTTP int(5);           oErrMsg varchar(40);         end-pr;       * Fin des elements exportes.       /if defined(IMPORT_PROTOTYPES)       /eof       /endif       *----------------------------------------------------------------------       * Declarations globales       * ---------------------------------------------------------------------       // ---------------------------------------------------------------------       // Recherche d'employé.       // ---------------------------------------------------------------------         dcl-proc MODULERH_rchEmp export;           dcl-pi *n;             iNumEmp char( 6 ) const;             oInfEmp likeds ( MODULERH_employe );             oErrHTTP int(5);             oErrMsg varchar(40);           end-pi;           // Recherche de l'employé.           exec sql             Select FIRSTNME, LASTNAME, DEPTNAME             into :oInfEmp.prenom, :oInfEmp.nom, :oInfEmp.service             From EMPLOYEE             Join DEPARTMENT on DEPTNO = WORKDEPT             Where EMPNO = :iNumEmp;           if sqlCode < 0;             oErrHTTP = 500;             oErrMsg = 'Erreur recherche de l''employé.';             return;           endif;           if sqlCode = 100;             oErrHTTP = 404;             oErrMsg = 'Employé inconnu.';             return;           endif;           // Tout s'est bien passé.           oErrHTTP = 200;           oErrMsg = *blanks;           return;         end-proc;

 

Beachten Sie die hervorgehobenen Anweisungen, wir kommen später darauf zurück, wenn wir unseren Webdienst vorstellen.

 

Um fortzufahren, werden wir einen Webservice-Server benötigen, auf dem unsere Dienste gehostet werden. Zu unserem Glück stellt uns IBM einen solchen auf der IBM i zur Verfügung: IWS (Integrated Web Services server).

Um darauf zuzugreifen, verwenden Sie die folgende URL: http: //mon_ibm_i:2001/HTTPAdmin

Dabei ist mein_ibm_i die IP-Adresse Ihrer Partition oder ihr DNS-Name.

 

ACHTUNG : Wenn die Seite nicht angezeigt wird, ist die Webadministrationsanwendung wahrscheinlich nicht richtig gestartet.

Führen Sie den folgenden Befehl auf einer 5250-Befehlszeile aus:

 

STRTCPSVR SERVER(*HTTP) HTTPSVR(*ADMIN)

 

Identifizieren Sie sich mit einem Profil, das das Recht *IOSYSCFG hat.

Klicken Sie auf der neu angezeigten Seite auf den Link „Create Web Services Server“ und lassen Sie sich durch den Assistenten führen.

 

Benennen Sie Ihren Server nach Belieben. Standardmäßig wird eine Apache-Instanz erstellt.

 

Wählen Sie die Ports, die der Server verwendet.

 

Sie haben die Möglichkeit, den Serverjob anzupassen, indem Sie ihm einen eigenen Jobd geben.

 

Ebenso können Sie das Benutzerprofil auswählen, das für die Serverarbeit verwendet wird. Denken Sie daran, diesen genau zu definieren. Eine gute Idee ist es, dieses Profil auf das Eigentümerprofil der Datenbank, mit der Sie arbeiten werden, zu setzen. Achtung, wenn Sie den Standardbenutzer QWSERVICE wählen, müssen Sie diesem ein Passwort zuweisen.

 

Bestätigen Sie schließlich die Erstellung des Servers, indem Sie auf die Schaltfläche „Finish“ klicken.

 

Da wir nun über einen Server verfügen, legen wir unseren ersten Dienst offen. Wählen Sie dazu den zuvor erstellten Server aus und klicken Sie auf den Link „Manage Deployed Service“.

Klicken Sie auf die Schaltfläche „Manage Deployed Service“. Klicken Sie dann auf die Schaltfläche „Deploy“ (Verteilen).

 

Auf der ersten Seite des Assistenten können Sie die ausführbare Datei auswählen, die Ihren Dienst implementiert. Seit V7.3 können Sie auch die Sprache sql verwenden, um den Dienst zu implementieren.

Bei Implementierungen in RPG IV können nur ausführbare Komponenten ausgewählt werden (Programme und Serviceprogramme). In unserem Fall wählen wir unser Serviceprogramm MODULERH.

 

Im nächsten Bildschirm können wir einen Namen für die Ressource auswählen. In unserem Fall nennen wir sie „Angestellte“, da wir mit Angestelltendaten umgehen.

 

Auf der folgenden Seite können wir den Zugriff auf den Webservice nur über einen sicheren Port (über SSL) beschränken. Da wir unseren http-Server nicht gesichert haben, antworten wir mit „No“.

Ebenso können wir eine Authentifizierung für diesen Webdienst verlangen.

In diesem Fall ist nur eine „grundlegende“ Authentifizierung verfügbar. In diesem Fall muss der Client im http-Header „Authorization“ einen auf dem System gültigen Benutzer und ein gültiges Passwort angeben.

 

Im nächsten Schritt können Sie im Fall von Dienstprogrammen die exportierte Prozedur auswählen, die den Dienst implementiert (hier modulerh_rchemp).

 

Der Assistent wird Sie später fragen, wie er den Kunden benachrichtigen soll, dass die Ausführung der Dienstleistung wie geplant oder mit einem Fehler verlaufen ist. Hier können Sie auf die standardmäßigen Rückkehrcodes und Fehlermeldungen einwirken.

 

Die nächste Seite ist die wichtigste. Hier wird beschrieben, wie die Kunden auf Ihre Dienstleistung zugreifen werden.

Wir können definieren:

  • Das verwendete http-Verb (hier GET)
  • Das für den Zugriff verwendete Url-Modell

Dieser ermöglicht es insbesondere, festzulegen, wo unsere Parameter platziert werden, wenn sie direkt in der URL bereitgestellt werden. Die zu verwendende Syntax wird sein: /{nom_parametre}

Bitte beachten Sie, dass Sie der Syntax auch einen regulären Ausdruck hinzufügen können, um die Gültigkeit des eingegebenen Parameters zu prüfen (hier \d+ für einen numerischen String mit mindestens einer Ziffer).

  • Eine Ausgabevariable, die den http-Rückgabecode füttert (muss in der RPG, die den Dienst implementiert, als Ganzzahl definiert werden).
  • Eine alphanumerische Ausgabevariable, die die Standardfehlermeldung ersetzt.
  • Die Datentypen, die als Eingabe akzeptiert werden (*Alle entsprechen allen verwalteten Typen: xml, json, Formulardaten, … => in diesem Fall muss der Client zwingend angeben, in welchem Informationstyp er liefert, damit der Server ihn versteht).
  • Die zurückgegebenen Datentypen: Das Tool ermöglicht die Rückgabe von Daten im xml- oder json-Format. Auch hier gilt: Wenn der Server beides bereitstellen kann, muss der Client angeben, welches er bevorzugt.
  • Wie werden die Ein- und Ausgabedaten dargestellt: gekapselt oder Name.

Schließlich können Sie auf diesem Bildschirm angeben, von wo die Eingabeparameter abgerufen werden sollen. In unserem Fall der Url unter Verwendung der Kennung num (erinnern Sie sich an diese, die in der Url-Vorlage definiert ist).

 

Auf dem nächsten Bildschirm können Sie einen bestimmten Benutzer für die Ausführung dieses Webdienstes festlegen. Das allgemeine Profil des Servers muss Zugriff auf dieses spezielle Profil des Webdienstes haben.

 

Im nächsten Bildschirm können Sie festlegen, welche Bibliotheken der Laufzeitumgebung hinzugefügt werden sollen.

 

Im vorletzten Bildschirm können Sie die Elemente konfigurieren, die an das Programm, das den Dienst implementiert, übergeben werden sollen.

 

Im letzten Bildschirm schließlich werden die eingegebenen Elemente zusammengefasst. Wenn Sie auf die Schaltfläche „Fertigstellen“ klicken, wird der Webservice bereitgestellt und gestartet.

 

Aber wie testet man unseren berühmten Webservice, fragen Sie mich?

Da der Webservice das Verb GET verwendet, wird ein einfacher Browser uns erlauben, diesen zu testen.

 

Für etwas komplexere Fälle haben Sie die Möglichkeit, sich an umfangreicheren Tools zu orientieren, wie :

  • CURL (wenn Sie Befehlszeilen nicht abschrecken): Mit diesem können Sie Ihre Anfrage vollständig parametrieren (Authentifizierung, Http-Header, …).
  • PostMan: Ein grafisches Werkzeug, das genauso umfassend wie CURL ist.

 

Ein kleines Beispiel mit PostMan: Fügen wir einen http-Header hinzu, der besagt, dass wir für die Antwort nur JSON wünschen (denken Sie daran, dass unser Webservice xml oder json liefern kann).

 

Und schon steht das ‚R‘ unserer CRUD-API, jetzt müssen Sie „nur noch“ die anderen Prozeduren erstellen, die die fehlenden Funktionen implementieren. Vergessen Sie nicht die Bedeutung der http-Verben, wenn Sie all dies einrichten :

C => POST

R => READ

U => PUT

Und D => DELETE.

 

Ich hoffe, dass dieser Beitrag das Thema ein wenig klären konnte. Wir sagen Ihnen bis zum nächsten Mal Bescheid, wenn wir uns in die Rolle des Kunden und nicht des Kellners versetzen können.

 

Haben Sie Fragen zu Webdiensten oder Ihrer IBM i-Plattform? Dann kontaktieren Sie uns unter 01 88 32 12 34 oder über das Kontaktformular.

Partager cet article