Integrare IBM i con servizi REST

Accedi per salvare

"Su IBM i non si possono chiamare le API." È una convinzione che sopravvive perché risale a quando era vera. Oggi le strade sono diverse, e la più semplice sta dentro il database: si scrive una SELECT e si ottiene la risposta di un servizio web.

La strada più diretta: SQL

Db2 for i mette a disposizione funzioni che eseguono chiamate HTTP. Il nome e la collocazione sono cambiati nel tempo — le funzioni originali stanno nello schema SYSTOOLS, mentre le release più recenti ne offrono una generazione più moderna in QSYS2 con prestazioni migliori e più controllo su intestazioni e autenticazione.

Prima di scrivere codice conviene quindi verificare cosa è disponibile sulla propria macchina:

SELECT ROUTINE_SCHEMA, ROUTINE_NAME
  FROM QSYS2.SYSROUTINES
 WHERE ROUTINE_NAME LIKE 'HTTP%'
 ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME;

L'elenco che esce dice esattamente quali funzioni si possono usare su quella release e in quale schema cercarle. Da lì, una chiamata a un servizio che restituisce JSON diventa una query, e il risultato si può leggere con JSON_TABLE per trasformarlo direttamente in righe e colonne.

Il vantaggio di questa via è che tutto ciò che sa fare SQL diventa disponibile a chiunque: RPG con SQL incorporato, un programma CL con RUNSQL, uno script, una procedura memorizzata.

Leggere JSON senza fatica

Il pezzo che di solito spaventa è l'analisi della risposta. In SQL non serve scrivere un parser:

SELECT *
  FROM JSON_TABLE(
         :risposta,
         '$.articoli[*]'
         COLUMNS (
           codice      VARCHAR(20)   PATH '$.codice',
           descrizione VARCHAR(100)  PATH '$.descrizione',
           prezzo      DECIMAL(11,2) PATH '$.prezzo'
         )
       ) AS dati;

Il JSON in ingresso esce come una tabella normale, con colonne tipizzate. Da un programma RPG con SQL incorporato si legge con un cursore, esattamente come qualsiasi altro risultato.

Per costruire JSON in uscita esistono le funzioni simmetriche JSON_OBJECT e JSON_ARRAYAGG, che compongono la struttura direttamente da una query.

L'altra direzione: esporre i propri programmi

Quando è il mondo esterno a dover chiamare IBM i, la strada supportata è l'Integrated Web Services server, incluso nel sistema operativo. Permette di pubblicare come servizio REST un programma o una procedura esistente, senza riscriverli: si indica l'oggetto, si mappano i parametri, e il server si occupa del resto.

Il punto delicato non è tecnico. Un programma nato per essere richiamato da un menù 5250 assume spesso un contesto — la lista librerie della sessione, un'area dati impostata prima, un utente specifico — che una chiamata HTTP non ha. Conviene quindi esporre programmi scritti per essere richiamati da qualsiasi contesto: parametri espliciti in ingresso, nessuna dipendenza dallo stato della sessione.

Quando serve qualcosa di più

Le funzioni SQL coprono bene le chiamate sincrone e i formati semplici. Diventano scomode quando servono autenticazioni articolate, gestione fine dei timeout, oppure quando il volume di chiamate è alto. In quei casi le alternative sono due:

  • QShell o PASE, dove si dispone di curl e di runtime completi come Node.js o Python. Un programma CL può lanciare uno script e leggerne il risultato da un file dell'IFS.
  • Un service program che richiama le API socket di sistema, per chi ha bisogno di controllo totale. È la strada più laboriosa e ha senso solo quando le altre non bastano.

Le cose che rompono l'integrazione

I certificati. Una chiamata HTTPS richiede che l'autorità che ha firmato il certificato del server remoto sia presente nell'archivio certificati del sistema, gestito tramite Digital Certificate Manager. È di gran lunga la causa più frequente di chiamate che falliscono subito, con errori che non sembrano avere a che fare con i certificati.

La codifica dei caratteri. IBM i lavora nativamente in EBCDIC, il mondo HTTP in UTF-8. Le funzioni SQL gestiscono la conversione, ma quando si passa da file dell'IFS o da PASE la conversione va dichiarata esplicitamente, altrimenti le lettere accentate diventano il primo sintomo di qualcosa che non torna.

I timeout. Una chiamata sincrona dentro un programma interattivo blocca l'utente finché il servizio remoto non risponde. Se il servizio è lento o non risponde affatto, la sessione resta appesa. Per le integrazioni non essenziali conviene una coda: il programma scrive la richiesta, un batch la elabora.

Da dove cominciare

Il modo più rapido per farsi un'idea è aprire Run SQL Scripts in ACS, eseguire la query sulle funzioni disponibili mostrata più sopra, e provare una chiamata verso un servizio pubblico che non richieda autenticazione. Se quella funziona, funziona tutto il resto: quello che resta è configurazione, non fattibilità.


Su quali versioni funziona

È l'argomento di questo elenco in cui la release conta di più: qui le differenze fra versioni sono sostanziali.

Funzioni HTTP in SYSTOOLS (SYSTOOLS.HTTPGETCLOB, HTTPGETBLOB e simili) — sono le più vecchie, documentate almeno da IBM i 7.3. Sono scritte in Java: ogni chiamata fa nascere una JVM, con il costo che ne consegue. Funzionano, ma sono la scelta obbligata solo se sulla macchina non ci sono le altre.

Funzioni HTTP in QSYS2 (QSYS2.HTTP_GET, HTTP_POST e simili) — sono la generazione successiva e sono quelle da preferire: offrono le stesse possibilità senza creare una JVM, e in più gestiscono autenticazione HTTP, proxy, numero di reindirizzamenti e opzioni SSL. Si appoggiano alle API di trasporto dell'Integrated Web Services client per ILE. Le versioni per dati binari (BLOB) di queste funzioni sono state consegnate a maggio 2023, con il gruppo PTF di livello 4 su IBM i 7.5 e livello 25 su IBM i 7.4.

La query mostrata nell'articolo per elencare le funzioni disponibili serve esattamente a questo: dice quale delle due generazioni c'è sulla tua macchina, senza doverlo indovinare.

JSON_TABLE — introdotta con il gruppo PTF del database SI99702 livello 14 su IBM i 7.2 e SI99703 livello 3 su IBM i 7.3, entrambi di novembre 2016. Non è disponibile su 7.1. È stata poi ampliata: la lettura diretta degli array JSON è arrivata con SF99704 livello 7 su 7.4 e SF99703 livello 18 su 7.3.

Se sei su una release che non ha nulla di tutto questo, restano due strade che funzionano ovunque: QShell o PASE con curl, richiamati da un programma CL e con la risposta letta da un file dell'IFS; oppure un programma che usa direttamente le API socket di sistema.

Integrated Web Services server — è incluso nel sistema operativo e serve per la direzione opposta, cioè esporre programmi e procedure come servizi. Le versioni si sono succedute nel tempo e il supporto REST è stato aggiunto dopo quello SOAP: la pagina IBM indicata fra le fonti riporta quale versione del server è disponibile per ciascuna release.

Fonti

← Torna al blog

Commenti

Nessun commento ancora. Sii il primo a commentare!

Devi avere un account per commentare. Accedi · Registrati