[NEWSboard IBMi Forum]
Seite 1 von 3 1 2 ... Letzte
  1. #1
    Registriert seit
    Jan 2012
    Beiträge
    1.120

    SQL Based Webservice im IWS: Get mit Input-JSON

    Guten Morgen,

    ich würde gerne mal wissen, ob folgenden über den IWS geht:

    Kann man einen SQL-basierten Webservice einrichten, der Daten holt (also HTTP-Methode GET) und der als Selektionsparameter nicht Path- oder Query-Parameter bekommt. Stattdessen sollen die Selektionsparameter in einem JSON Objekt an der Service übergeben werden.

    Wenn ich versuche, so etwas im IWS zu implementieren, kann ich das Input-Json nicht als Parameter angeben. Die Meldung ist, dass das nur bei den Methoden PUT, POST oder PATCH ginge.

    Mit POST-Services klappt es. Das haben wir bereits probiert. Aber was macht man, wenn man viele, eventuell sehr lange Selektionsparameter bei einem GET-Service benötigt? Path-Parameter sind sehr unhandlich und Query-Parameter sind ja nicht unendlich lang.

    LG, Dieter

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Schau mal hier in diese Diskussion, ins besonders auf Rainer Ross's Seite.
    http://newsolutions.de/forum-systemi...4-IWS-und-Body
    http://newsolutions.de/forum-systemi...349#post109349
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Nov 2020
    Beiträge
    331
    Ich persönlich bin kein Freund von dieser Einordnung (GET = Lesen, POST = Schreiben usw.).
    Vor allem da auf technischer Ebene es große Unterschiede gibt und nicht jedes "Lesen" mit einem GET abgedeckt werden kann ... so entstehen schnell Wildwuchs und Ausnahmen.

    Zum technischen Unterschied:
    Da beim GET alle Parameter über den HTTP-Header (z.B. URL) übermittelt werden, werden diese Daten unverschlüsselt über die Leitung übertragen.
    Bei POST liegen die Daten im HTTP-Body und diese sind bei HTTPS immer verschlüsselt.
    Auch bei der Länge ist GET eingeschränkt gegenüber POST.
    Dann gibt es noch das Thema mit Sonderzeichen oder Binärdaten usw.

    Meine persönliche Regel:

    GET wird verwendet, wenn nur wenige Parameter, übertragen werden, die nicht verschlüsselt werden müssen (z.B. in der URL).

    Gibt es mehr Daten, vielleicht sogar mit einer komplexeren Struktur (JSON, XML), wird POST verwendet.

    lg Andreas

  4. #4
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Vielen Dank an euch für die Antworten.
    Das zeigt mir, dass ich technisch wohl nichts übersehen habe beim GET. Aus meiner (pragmatischen) Sicht würde auch nichts gegen POST sprechen. Aber ich weiß, dass es da Diskussionen bzgl. Einhalten von Standards geben wird.

    Vielen Dank.
    Ihr habt mir sehr geholfen.

  5. #5
    Registriert seit
    Nov 2020
    Beiträge
    331
    Zitat Zitat von dschroeder Beitrag anzeigen
    Aber ich weiß, dass es da Diskussionen bzgl. Einhalten von Standards geben wird.
    Das gäbe es sicher. Manchmal macht man lieber einen Spagat und fährt drei mal um den Block, nur damit man sich das Zertifikat "Standard" aushändigen kann ohne zu überlegen ob es technisch überhaupt sinnvoll ist.
    Gerade das Thema Security & Verschlüsselung werden dann für den "Standard" geopfert.

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Bzgl. REST-API's hat sich aber gerade wegen JSN/XML-Paramtern POST durchgesetzt.
    a) ist es erheblich flexibler und Datensicher
    b) in urls sind Sonderzeichen u.ä.in der %xx-Notation zu übergebem. Da sind JSON/XML's als String nicht möglich.
    https://de.wikipedia.org/wiki/URL-Encoding
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    Jan 2012
    Beiträge
    1.120

    Talking

    Ich habe mich jetzt (auch aufgrund eurer Antworten) dazu durchgerungen, einen POST Service zu implementieren. Ich habe eine SQL-UDF erstellt, die einen Clob als JSON-Input bekommt und die einen Clob als JSON-Antwort zurückgibt.
    Die Antwort-Clobs werden nicht vom IWS generiert, sondern ich baue sie selber mit den SQL-JSON-Funktionen zusammen.

    Jetzt habe ich noch ein Problem:
    Im IWS definiere ich das auszuführende SQL, also im wesentlichen den Aufruf meiner UDF. Ich würde sehr gerne den HTTP-Statuscode von meiner UDF aus beeinflussen. Wenn ich den IWS Wizzard richtig verstehe, gibt es da aber nur die beiden Ausprägungen 200 bei Erfolg und 500 bei Misserfolg. Ich kann den Code nicht selber beeinflussen, so dass z.B. ein 404 zurückkommt. (Klar, ich kann die 500 im IWS z. B. fest durch 404 ersetzen. Aber dann kommt ja immer 404 zurück. Das ist natürlich nicht, was ich will.)

    Aber das ist noch nicht alles:
    Unsere RPG-based Webservices geben bei Erfolg das angeforderte Antwort-Json zurück. Bei Misserfolg kommt ein standardisiertes Fehler-JSON zurück, dass z.B. die Fehlernachricht, das betroffene Programm usw. enthält.

    Bei meinem SQL basierten Webservice habe ich da jetzt ein Problem:
    Wenn die SQL-UDF keinen Fehler enthält, kommt das gewünschte JSON zurück und der Statuscode 200 wird vom IWS zurückgegeben.
    Wenn ich aber einen fachlichen Fehler habe (z.B. Authentifizierungstoken ungültig), erzeuge ich das Fehler-JSON-Objekt und gebe das zurück. Das ist technisch gesehen aber kein Fehler für SQL. Deshalb kommt auch im (fachlichen) Fehlerfall als Statuscode 200 zurück. Das ist sehr unschön.

    Ich habe bereits damit experimentiert, mittels der SIGNAL Anweisung im SQL einen SQL-Fehler auszulösen. Dann gibt IWS auch wirklich den Statuscode 500 zurück. Aber dann kommt mein Antwort-JSON nicht zurück, sondern ein SQL-Message-String.

    Code:
      -- Prüfung Authorization:
      set resultClob = clob(DAX99##_checkAuthorization(token, clientId,
                                role, pgmName, procName, 0, httpStatusCode));
    
    
      -- Prüfung Authorization nicht erfolgreich:
      if length(resultClob) > 0 then
         -- Class Code 28: Invalid Authorization Specification
         signal SQLSTATE '28000'
         set Message_Text = 'authorization failed';
         return resultClob;
      end if;
    Rückgabe im Fehlerfall ist: (Statuscode 500)
    [SQL0438] authorization failed (SQLState=28000, ErrorCode=-438)




    Ich hätte aber gerne zurück: (Statuscode 500)
    Code:
    {  "daxErrorObject": { 
            "errorCode": "ERROR_OAUTH_TOKEN", 
            "errorMessage": "Das OAuth-Token konnte nicht verifiziert werden.
         "messageType": "ERROR", 
            "routine": "DAXWS_dataRetriever", 
            "field": "", 
             "details": null  }
    }
    



  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Das ist eben der Unterschied auch zur SQL-Aufrufart SQL-Style.
    In diesem Fall hast du zusätzlich neben Feldern, NULL und Return auch den SQLSTATE und SQL-Diagnostics.
    Ggf. ist das eher ein Ansatz um eine SQL-Fehlermeldung und keine HTTP-Fehlermeldung zu erzeugen.
    Zur Not hilft auch noch das MSG-API QMHSNDPM mit dem Senden einer ESCAPE-Message.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  9. #9
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Hallo Baldur,
    ich verstehe deine Antwort nicht. Möglicherweise habe ich meine Frage nicht richtig rübergebracht.
    Deshalb noch mal etwas klarer:

    1. Ich möchte einen Webservice mit dem IWS erstellen.
    2. Da die Rückgabewerte bei RPG-basierten Services relativ klein sind, möchte ich einen SQL-basierten Service erzeugen.
    3. Der SQL-basierte Service besteht aus einer SQL-UDF, die ein clob (mit JSON-Inhalt) zurückgibt.
    4. Im Erfolgsfall wird ein JSON zurückgeliefert und der http Statuscode wird (automatisch vom IWS) auf 200 gesetzt. Das ist genau so, wie ich es haben möchte.
    5. Im Fehlerfall (fachlicher Fehler) möchte ich ebenfalls ein JSON mit den Fehler-Informationen zurückliefern und ich möchte den HTTP-Statuscode auf 400 (oder wegen mir auch 500) setzen. Das klappt nicht.
      Um den IWS dazu zu bewegen, den Statuscode auf ungleich 200 zu setzen, muss ich einen (technischen) SQL-Fehler erzeugen. Wenn ich das tue, kann ich aber kein JSON mehr zurückgeben.


    Falls da jemand eine Idee hat ...

    LG, Dieter

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    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.

    https://www.ibm.com/docs/en/i/7.5?to...eter-style-sql

    Siehe SQLSTATE und Diagnostic Message.
    Das kannst du wohl auch kurz testen, in dem du eine unbekannte Funktion aufrufst. Da wiird dir bestimmt mehr also nur der Errorcode zurückgegeben.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  11. #11
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Zitat Zitat von Fuerchau Beitrag anzeigen
    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.

  12. #12
    Registriert seit
    Nov 2020
    Beiträge
    331
    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:
    Code:
    return Response({'a':'b'}, status=400, mimetype='application/json')
    Last edited by Andreas_Prouza; 08-04-24 at 12:52. Grund: Formatierung

Similar Threads

  1. IWS Server mit SQL und Multirow JSON/XML als Input
    By Andreas_Prouza in forum IBM i Hauptforum
    Antworten: 10
    Letzter Beitrag: 18-01-23, 14:30
  2. IWS nested JSON bei POST Aufruf mit SQL verarbeiten
    By ismiavoiwuascht in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 17-10-21, 21:17
  3. HTTPS Aufruf mit JSON Input
    By derMuller in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 05-12-17, 11:05
  4. Parameternamen bei Webservice REST im JSON-Format
    By Flappes in forum NEWSboard Programmierung
    Antworten: 4
    Letzter Beitrag: 01-06-17, 08:01
  5. Abstimmung_neu:Server-Based-Computing
    By Burgy Zapp in forum IBM i Hauptforum
    Antworten: 0
    Letzter Beitrag: 17-12-01, 01:48

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •