Creare Web Services per IBMi (AS400) in 8 min

I Web Services Integrati (IWS) di IBM generavano solo SOAP Web Services.

Le cose sono cambiate nel corso degli anni, come ha sottolineato Tim Rowe di IBM in molte occasioni, l’IWS è stato aggiornato in modo significativo.

Ora non supporta solo Rest web service, ma consente che richiesta e risposta vengano fatte con formati che vanno dal raw test, all’XML fino al JSON.

La Subprocedura RPG

Prima di entrare nel dettaglio di come usare il wizard IWS per settare il servizio, abbiamo bisogno di stabilire alcuni punti riguardo il codice RPG che dovremo usare. 

Il  sorgente qui sotto rappresenta una semplice subprocedure quando passa un Customer Number (CustNumber) recupera il nome base e le informazioni di indirizzo per quel cliente. Se quel cliente non esiste, il nome viene settato come *** Not found ***.

Partendo da (A) abbiamo definite la struttura dati custInfo che sarà usata per costruire la risposta.

Nota che abbiamo semplicemente messo in lista il campo nomi che abbiamo richiesto dal file CustMast. L’altro beneficio nel creare codice in questo modo è che quando capita un CHAIN di successo, tutti gli altri campi nel nostro DP saranno completati come per magia. Non è necessario il copying.

Lo stiamo sottolineando perché questa aggiunta è quello che rende possibili l’uso di questa routine sia nel nostro RPG che nel Web service. Questo “elemento magico” è la keyword RTNPARM. Per spiegare meglio come questo può aiutare, date un’occhiata a come possiamo chiamare questa routine in un programma RPG regolare. Apparirà normalmente circa così:

CustInfoData = GetCustInfo( custNum );

Il problema è che il wizard del Web service consente solo l’uso di un numero intero di 4-byte come valore di ritorno.

Abbiamo invece una moltitudine dati strutturali più grandi di 4 byte!

Non voglio scendere nei dettagli ma questa è una limitazione imposta dal sottostante Java.

La magia della keyword RTNPARM è che prende il valore di ritorno e lo converte in un parametro (il primo).

RPG ha introdotto questa caratteristica come un incremento di performance per i valori di ritorno grandi. Ma questo ha anche il piacevole effetto di consentire a quelle routine di essere usate dal wizard del Web service. Come possiamo vedere questa routine ha due parametri e nessun valore di ritorno. E tutto questo è stato fatto senza impattare sulla capacità di lavorare regolarmente con i programmi RPG nel modo in cui lo facciamo normalmente. Si tratta di un beneficio inaspettato!

Ora è possibile non solo applicare questa tecnologia alle subprocedure che state riproponendo come Web services ma anche come un modo semplice per poterle usare da Java e da altre strutture con la stessa limitazione di base. Siamo felici di vedere che questa informazione è stata aggiunta al documento IWS, non era un’opzione ovvia.

     h NoMain Option(*SrcSTmt : *NoDebugIO)

     fCustMast  IF   E           K DISK

(A)  d CustInfo        ds                  Inz
     d   Cust#
     d   Name
     d   Addr
     d   City
     d   State
     d   Zip

(B)  p GetCustInfo     b                   Export
     d                 PI                  LikeDS(CustInfo)
     d                                     RTNPARM
     d   CustNumber                   5s 0

     d CustNotFound    c                   '*** Not found ***'

(C)     Chain ( CustNumber ) CustMast;

        If Not %Found(CustMast);
(D)       Reset CustInfo;       // Clear out all data
          Cust# = CustNumber;   // Set customer number requested
          Name = CustNotFound;  //   and error code
        EndIf;

        Return CustInfo;

     p GetCustInfo     e
 

(C) È semplice il processo che recupera i dati dei clienti. Lo abbiamo evidenziato qui perché ci permette di menzionare rapidamente una cosa che abbiamo osservato di recente. Notate che il campo chiave è fra parentesi? Facendo questo non dobbiamo garantire che la data, la grandezza, etc…. della chiave corrispondano al file. Il compilatore si occuperà delle differenze.

(D) Verifica se il processo ha avuto successo. Se è così tutti i dati richiesti sono già caricati e non c’è altro da fare se non ritornare ai risultati. Se il cliente non è stato trovato, in ogni caso, dovremo pulire i risultati dall’operazione precedente (RESET) e settare il numero del clienti in questione e un messaggio di errore nello spot appropriato.

Mentre compilate il codice accertatevi di specificare che desiderate generare Program Call Markup Language (PCML). Vi suggeriamo di usare l’opzione PGMINFO (Program Information) per incorporare questi dati nel modulo specificando PGMINFO (*YES *MODULE). Il PCML fornirà al wizard IWS l’informazione che necessità per interfacciarsi con l’RPG.

Una volta che il codice è compilato come un modulo, lo aggiungiamo al Service Program e questo è il Service Program che verrà usato dal Web service. Vale la pena notare che IWS può anche usare gli oggetti del programma, ma in questo caso vogliamo dimostrare come possa riutilizzare una struttura preesistente.

Settare il Web Service

Non entreremo nel dettaglio perché IBM ha diverse pagine Web in cui descrive il processo.

Abbiamo in ogni caso prodotto un breve video del processo che potete vedere qui.

Queste sono le principali pagine IBM che potete trovare utili:

Immagine correlata

Testare il Web Service

A differenza della implementazione di un Web service SOAP, IBM non fornisce un test durante la costruzione di un Web services REST. Ad essere onesti siamo contenti di questa decisione; abbiamo sempre osservato che i tester per SOAP sono difficili da usare e decisamente non intuitivi. Abbiamo sempre usato il toll free SOAPUI (https://www.soapui.org/downloads/soapui.html ) per testare i Web services.

Fortunatamente per noi c’è stato un upload di questo prodotto per permettere di testare I Web services REST in aggiunta al servizio di support per SOAP.

In ogni caso, c’è un modo più semplice di testare i Web services REST. Basta semplicemente usare il vostro browser! Molti servizi REST (inclusi quelli creati con IWS) sono capaci di sfruttare il protocollo http usato dai browser Web. Quindi basta semplicemente inserire la richiesta che volete fare nell’URL (il wizard IWS vi mostrerà il formato base per il messaggio) e la risposta apparirà nel browser. Nel nostro test di un nuovo servizio abbiamo scelto di avere la risposta in formato XML, perché se stiamo utilizzando il servizio da un programma RPG sarà più semplice processare i risultati attraverso XML-INTO. Inoltre, come potete vedere nella figura, questo rende più facile la visualizzazione dei risultati. Notate che l’elemento XML che contiene i risultati è chiamato _RTNPARM, dovrebbe suonarvi famigliare. All’interno di quell’elemento ci sono i campi nella struttura dati ritornati. Se la subprocedura rimanda il valore con parametri regolari l’elemento avrà il nome del parametro.

Nel nostro esempio il Web service da usare (custinfo) e il numero cliente (00345) sono entrambi specificati nell’URL di base. Lo abbiamo settato inoltre per avere il numero cliente da passare come parte della query, in questo caso l’URL avrebbe questo aspetto:

http://ideveloper:10021/web/services/custinfo/?custnumber=00345

Quale usare? Vi lasciamo prendere la vostra decisione. La nostra opinione è che abbia senso avere l’informazione che viene sempre richiesta (il numero del cliente) nell’URL ma che avremmo dovuto utilizzare i parametri nella stringa di query per identificare i singoli campi se avessimo voluto, per esempio, estendere il web service per consentire l’updating delle informazioni del cliente.

Il buono, il fastidioso ed il cattivo

Abbiamo ancora molta strada da fare nell’esplorazione di queste nuove capacità e vi riferiremo le nostre nuove scoperte. Ma abbiamo alcune idee da condividere. È possibile che alcuni di questi problemi siano già stati affrontati ma non abbiamo trovato niente riguardo i Web Service REST.

ll buono

  • Le performance del servizio sono eccellenti, molto più veloce di quello che ci aspettavamo. Come si comporta con un carico di lavoro elevato non lo possiamo dire ma i report che abbiamo letto sembrano indicare che la performance è buona. È certamente più facile, dal punto di vista del programmatore, creare un servizio piuttosto che un metodo come abbiamo descritto prima. Non bisogna preoccuparsi della gestione delle richieste, limitatevi a scrivere codice per accettare parametri e restituire un risultato.
  • Le funzionalità previste nella procedura guidata per mappare i parametri, etc., sono chiare e semplici.

ll fastidioso

Sembra una lunga lista, in qualche modo sleale perché alla fine questo insieme di tool è grandioso ma ha sicuramente margini di miglioramento.

  • Il più grande problema che abbiamo è la documentazione. Da quello che capiamo, uno degli obiettivi di IWS è rendere possibile per le persone che non sanno niente di Web services crearne uno. Il problema è che la terminologia usata nella documentazione è, per la maggior parte, un sotto-dialetto dello UNIXese e presuppone che si capisca almeno qualcosa di Web services.Per esempio, nella guida passo per passo a cui abbiamo fatto riferimento prima, al punto 10 viene detto “Specificare quale trasporto di informazioni relative alla richiesta del cliente deve essere passato al codice di implementazione del servizio Web”. Cosa? Visto che abbiamo familiarità con la programmazione base in RPG e PHP, la terminologia non è completamente aliena per noi, ma molti di quelli abituati all’RPG lo troveranno un ostacolo.Certo è forse ingiusto parlare di questo problema riguardo IWS. Si tratta di una problematica che abbiamo visto spesso. Se IBM vuole veramente che queste funzionalità vengano utilizzate, questa questione dovrà essere affrontata.
  • Il wizard consente di utilizzare un codice regolare, per limitare il contenuto di un campo particolare (diciamo) numerico. Ma se il tuo input infrange le regole non c’è alcun messaggio di errore. Semplicemente non c’è output. Questo rende la validazione abbastanza inutile. Sarebbe meglio forzare la validazione nel codice RPG, in questo modo ritornerebbe un messaggio di errore.
  • Mentre in tema di valori numerici, per qualche ragione, lo strumento sembra restituire i valori numerici senza gli zeri. Lo si può osservare nell’esempio sopra. Poiché lo strumento conosce la lunghezza effettiva del campo, non capiamo perchè ci sia questo problema.
  • Quando costruiamo pagine web regolari su IBM i gli URL non sono case sensitive, come del resto non lo sono per la maggior parte dei siti web. Questo probabilmente può essere modificato da qualche parte nella configurazione del server, ma non abbiamo trovato nessun riferimento a questo problema.

Ci sono altri problemi che potremmo citare, ma non vogliamo criticare quello che per noi è un grande strumento. Pensiamo però che siano cose che dovete sapere o si finirà per perdere un sacco di tempo a guardare degli schemi bianchi chiedendosi perché il servizio non è configurato nel modo corretto.

ll cattivo

C’è una sola cosa che sentiamo sia veramente sbagliata tanto da meritare l’etichetta di “cattivo” ed è il fatto che non c’è modo, almeno per quello che abbiamo visto, di modificare la definizione del servizio utilizzando la procedura guidata.

Se hai bisogno di cambiare un parametro, o di passare dal supporto XML aggiungendo JSON, l’unico modo per farlo è cancellare il servizio esistente e ricrearlo. Se ci sono molti parametri e altri settaggi coinvolti questo diventa non solo fastidioso ma produce errori.

per scrivere un webservice da AS400 bisogna

  1. conoscere l’RPG ILE il che significa 3 gg di corso per chi conosce l’RPG
  2. poi altri 3 per imparare a fare i webservices   
  3. e poi ogni webservice richiede il suo tempo

La soluzione

con OPEN API STUDIO

  1. non devi conoscere l’ILE
  2. impari il tool in 15 minuti
  3. poi fai webservice da IBMi (AS400) in un minuto

guarda come creare webservices in 8 min

registrati per avere maggiori informazioni

chiamaci 0423605099 o mandaci un’email