PDA

View Full Version : SQL Based Webservice im IWS: Get mit Input-JSON



Seiten : 1 [2] 3

dschroeder
08-04-24, 12:29
Wenn eine SQL-Funktion einen SQLSTATE und SQL-Diagnostics zurück gibt, gehe ich ganz stark davon aus, dass der Text im Response zurück gegeben wird. Ein zusätzliches JSON macht da keinen Sinn.


Es geht hier allerdings nicht primär um den Aufruf einer SQL-Funktion, sondern um einen Webservice, der im IWS als sogenannter "SQL-based" -Service definiert ist. Bei einem Webservice macht ein JSON (meines Erachtens) immer Sinn. Der Konsument des Webservices soll ja gar nicht wissen, dass der Webservice intern SQL-basiert arbeitet. Er soll als Antwort immer ein Json und den passenden Statuscode zurückbekommen. Mit einem SQL_status kann der Konsument nichts anfangen.

Andreas_Prouza
08-04-24, 12:51
Der IWS ist sehr beschränkt in vielen Bereichen (dabei rede ich noch nicht einmal von Versionsverwaltung, Deployment usw.).
Deshalb habe ich mit Python auf der IBM i ein kleines Beispiel-Projekt auf Github für WebServices erstellt:
https://github.com/andreas-prouza/python-webapi

Das habe ich schon bei einigen Kunden produktiv seit mehreren Jahren im Einsatz.
Noch nie ein Absturz oder Probleme.
Und solche Anforderungen wie du sie Beschrieben hast, sind ein einfacher 2-Zeiler.

Das würde in Python so aussehen:

return Response({'a':'b'}, status=400, mimetype='application/json')

dschroeder
08-04-24, 13:04
Hallo Andreas,
ich würde gerne auf eine weitere Technologie, in der sich bei uns keiner auskennt (Python), verzichten.

Eine schöne Webservice Lösung in nativem RPG fände ich toll.

Andreas_Prouza
08-04-24, 13:46
Hi Dieter,

Das verstehe ich auch sehr gut.
Ergänzend sei hier nur angemerkt, dass die Kunden bei denen ich es im Einsatz habe sich ebenfalls großteils nicht mit Python auskennen.
Ich habe ihnen das Grundgerüst installiert und der Rest ist Copy/Paste wodurch man sich auf das SQL konzentrieren kann.
Somit war es für die Kollegen einfacher dort eine Änderung/Erweiterung durchzuführen als PHP, Java oder IWS ... so wie ja auch bei deinem Beispiel jetzt :-)
Außerdem verwende ich Python nur für die Schnittstelle zur Web-Welt. Alles andere bleibt in SQL/RPG.

Auch das Generieren oder Auslesen von JSON/XML ist ein 1 Zeiler.
Ich bin ein Fan von SQL und RPG, jedoch im Vergleich zu (z.B.) Python benötigt man viel mehr Aufwand und ist viel komplexer ein JSON/XML.

Ich sag nur, dass ihr immer wieder in Zukunft in solche Sackgassen kommen werdet und dann viel Aufwand betrieben wird dort wieder raus zu kommen.
Ist natürlich immer eine Frage von Kosten/Nutzen und ob man das ganze langfristig betreiben will (Stichwort: Nachwuchs), oder nur bis zur Ablöse irgendwie am Leben erhalten möchte.

Ich beschäftige mich seit sehr langer Zeit, sehr viel mit WebServices. Wenn ich einen alternativen Hinweis für dein Problem hier hätte, würde ich ihn dir gerne liefern.

dschroeder
08-04-24, 14:12
Vielen Dank für deine ehrliche Antwort, Andreas.

Wenn ich deine Lösung richtig verstehe, sähe es folgendermaßen aus:


Jemand (z.B. Du) installiert ein bisschen Software auf unserem System. Damit müssten wir uns nicht rumschlagen.
Wir zusammen würden (sehr kleine) Python Scripte erstellen, die uns den "Webservice-Kram" vom Hals halten. In so einem Script (was man einfach kopieren und anpassen kann) können SQL-Anweisungen ausgeführt werden.
Die Scripte können Clobs oder Blobs zurückliefen.
Ich nehme mal an, dass wir den IWS dann nicht mehr brauchen würden. Es würde je Service ein Python Script erstellt und als SBMJOB ausgeführt?
Die Jobs könne ich debuggen (ich meine nicht das Python, sondern das, was im SQL aufgerufen wird (UDF, RPG). Oder läuft das in einer "merkwürdigen" Umgebung, wo man nicht rankommt?


Habe ich das grob so korrekt verstanden?

Andreas_Prouza
08-04-24, 17:41
@1: Genau, entweder habt ihr jemanden mit Erfahrung mit Python, ansonsten unterstütze ich gerne

@2: Genau, im Prinzip ist es immer der gleiche Aufbau:

Funktion erstellen (z.B. hier get_active_jobs(subsystem))
Die gewünschte Route (URL-Pfad) dafür festlegen (@app.route)
Funktions-Code selbst


cnxn = pyodbc.connect('DSN=*LOCAL')
cursor = cnxn.cursor()


@app.route('/get-active-job/<subsystem>'</subsystem>, methods=['GET', 'POST'])
def get_active_jobs(subsystem):

cursor.execute("Select job_name, subsystem, job_type, thread_count, cpu_time, function_type, FUNCTION, job_status \
from table(QSYS2.ACTIVE_JOB_INFO(SUBSYSTEM_LIST_FILTER=>upper(?))) t", subsystem)

rows = cursor.fetchall()

return jsonify(result)



Diesen Block kannst du kopieren. Statt SELECT kannst du auch einen CALL absetzen (dadurch auch RPG direkt aufrufen) ... halt alles was SQL unterstützt.

@3: CLOB & Co sind kein Problem. Hab ich auch in Verwendung. Python & ODBC handeln das automatisch.

@4: Genau, kein IWS. Man kann (und sollte) einen vorgelagerten Webserver verwenden (Apache oder NGINX).
Dieser leitet die Anfragen weiter an den Applikation Server (Python).
Ist beim IWS genauso. Dadurch können im WebServer diverse Konfigurationen vorgenommen werden, wie Berechtigungen und Verschlüsselung (HTTPS) und der Applikations Server braucht sich nur um die Verarbeitung kümmern.

Du kannst die Funktionen in diverse Skripts verteilen (am Besten mit entsprechender Ordnerstruktur je Bereich).

Grundsätzlich können die unterschiedlichen Requests alle unter dem gleichen Applikations-Server laufen.
Man kann aber auch mehrere WebServer und/oder mehrere Applikations-Server verwenden wenn man will. Es muss halt die Python App (das Grundgerüst) mehrfach kopiert werden.

@5: Zunächst gibt es die Möglichkeit vom Logging. Du kannst alles im Python in ein Log ausgeben lassen.
Für mich reicht das aus um damit den SQL Aufruf nachzustellen und ggf. interaktiv zu debuggen.
Ansonsten verbindet sich Python via ODBC mit der DB2. Dadurch sind das normale Jobs in der QUSRWRK.
Um diese Jobs direkt zu debuggen gibt es mehrere Möglichkeiten. Man könnte z.B. im RPG ein DSPLY mit Antwort-Aufforderung einbauen. Dadurch steht der Job auf MSGW und man kann sich via STRSRVJOB verbinden und mit STRDBG debuggen.

In der Regel reicht jedoch das Logging aus. Im IWS hab ich ja gar kein Logging, bis auf das was der IWS von sich aus ausgibt.

Fuerchau
08-04-24, 18:21
Als weitere Alternative wird auch Node.js unterstützt. Hier ist die Unterstützung genauso native und die Node.js-Community ebenso groß.
Es kommt ja immer nur darauf an, die richtigen Externen Mitarbeiter zu finden, die einem die Probleme abnehmen. Ich lebe davon seit 1997.

dschroeder
08-04-24, 19:07
Vielen Dank an euch beide!

Ich werde das hier mal ansprechen. Mal sehen, ob wir einen der er beiden Wege gehen.

Fuerchau
08-04-24, 22:02
Node.js läuft native auf der IBM i, ein zusätzlicher Web-Server ist nicht erforderlich, da Node.js Web-Requests behandeln kann, genauso auch wie auch DB-Zugriffe.
Man braucht auch keine Angst vor Performance haben. Mein Kunde betreibt einen Web-Shop, der 1000de JSON-Abfragen sowie Order-Uploads pro Minute schafft, ohne die ERP-Software zu beeinträchtigen.

Andreas_Prouza
09-04-24, 06:03
Node.js wird genauso wie Python oder mittlerweile auch PHP über die Open Source Produkte (YUM) installiert.

Einen eigenen Webserver zu verwenden hat nichts mit der Sprache zu tun. Keine Sprache verlangt dies. Der eigene Webserver hat security technischen Hintergrund, zur Abtrennung zwischen der Web-Welt und der App.
Deshalb hab ich oben geschrieben "Man kann (und sollte)". Es ist ein schlechtes Design wenn man HTTP Konfigurationen (z.B. SSL mit Zertifikaten) in die Applikation einbaut. Das wird auch überall so empfohlen, selbst bei internen WebApps.

Node.js hab ich früher auch benützt und sogar Schulungen gehalten.
Bis zum Zeitpunkt als während einer Schulung ein Kunde ein Update benötigt hat, was darauf zur Folge hatte, dass danach gesamt Node.js nicht mehr funktionierte.
Kein Downgrade oder neu installation von Node.js hat dabei geholfen. Das ging soweit, dass auch Profound (welches auch Node.js verwendete) nicht mehr funktionierte. Das BackUp für die gesamte Partition musste her. (Zum Glück alles "nur" auf der Dev).
Der Erfinder von Node.js hat später dann Deno ins Leben gerufen, da es mit Node.js in einigen Punkten Probleme gab. Bei Deno meinte er, habe er alle Fehler, die er bei Node.js gemacht habe, beseitigt.

Das schöne an Python ist, es ähnelt in einigen Punkten RPG.
Es hat sehr viele einfache Features, wodurch man sich viel Code ersparen kann und es auch sehr schnell ist.
Möchte ich eine Sprache mit super Performance wo ich jeder Millisekunde hinterher weine, würde ich in Rust bzw. auf der IBM i sowieso RPG nehmen.