Smeup ha sviluppato una nuova funzionalità che permette di eseguire delle interrogazioni collegando diverse FUN ed ottenendo dei risultati aggregati, assolvendo lato server al lavoro di recupero ricorsivo dei dati, che altrimenti dovrebbe essere eseguito lato client. Questa funzione ha preso il nome di Smeup Data Aggregator.

Il concetto è molto semplice: si richiede una lista di record tramite una FUN, dove ognuno di essi può avere a sua volta altri record di dettaglio. Un esempio potrebbe essere quello di una lista di clienti in cui per ogni cliente vogliamo vedere anche la lista dei suoi indirizzi di spedizione.

Questo permette a chi deve interrogare i dati di eliminare “complessità” nella sua procedura di lettura, di risparmiare traffico di rete e tempo di esecuzione. Il concetto è molto simile a quanto viene eseguito su GraphQL ed è la direzione che si sta diffondendo ormai ovunque nell’ambito informatico, lasciando indietro il classico concetto di API REST.

L’aggregator

Qui sotto mostriamo un esempio di definizione che può essergli passata:

{
        "alias": "LEVELS",
        "fun": "F(EXB;LOA10_SE;ELE) 1(LI;CNCOL;*) INPUT(Sch(T/CD*) SchPar() NTit(1) ChL(1) Opz(No) NK01(1) FSA(PAOLO) RPa(00100) Flt(S) Refresh(1))",
        "Relations": [{
                "name": "TOOLTIP1",
                "fun": "F(EXB;WESER_23;MAT.PRI) 1(CN;COL;{ID_LI})",
                "Relations": [{
                        "name": "LISTA CLIENTI",
                        "fun": "F(EXB;LOA10_SE;ELE) 1(LI;CNCLI;*) INPUT(Sch(S/DFT) SchPar() NTit(1) ChL(1) Opz(No) NK01(1) FSA(SEDE = {U/011} ,) RPa(00100)   Flt(S)  Refresh(1) )"
                    }
                ]
            }, {
                "name": "TOOLTIP2",
                "fun": "F(EXB;WESER_23;MAT.SEC) 1(CN;COL;{ID_LI})"
            }
        ],
        "funParameters": []
    }

Vediamo, in sintesi, come l’aggregator utilizza queste informazioni e le operazioni che esegue:

  1. Possiamo notare che nella struttura LEVELS, è stata definita una FUN (EXB;LOA10_SE;ELE) più esterna che legge i collaboratori con il nome “Paolo”.
  2. Sotto questa FUN, c’è un attributo Relations nel quale vengono specificate appunto le relazioni con altre entità di cui si vogliono leggere/restituire i dati. In questo caso abbiamo definito 2 relazioni: TOOLTIP1 e TOOLTIP2:

TOOLTIP1, è associata alla FUN F(EXB;WESER_23;MAT.PRI). Per ogni collaboratore, quindi, viene eseguita una seconda FUN che legge dati della sua sede di appartenenza. All’interno di TOOLTIP1 è stata definita un’ulteriore relazione definita con il nome LISTA CLIENTI. Per ogni sede, quindi, viene eseguita una terza FUN (EXB;LOA10_SE;ELE) che ne restituisce i clienti.

TOOLTIP2, invece, è associata alla FUN (EXB;WESER_23;MAT.SEC) che restituisce i dati del collaboratore.

In poche parole, abbiamo una FUN master (collaboratori) che tramite le “Relations” stabilisce quali altre FUN devono essere eseguite al sui interno: “TOOLTIP1” (sede di appartenenza) e “TOOLTIP2” (dati collaboratore). All’interno di TOOLTIP1 abbiamo un’ulteriore livello di lettura “LISTA CLIENTI” (elenco dei clienti della sede di appartenenza).

L’intero flusso può essere schematizzato come nella figura seguente:

Schema che mostra il funzionamento logico dello Smeup Data Aggregator

È importante evidenziare che ogni FUN che viene eseguita aggiunge i propri risultati all’output finale. Nella definizione che viene passata in input all’aggregator (LEVELS) non è possibile decidere i campi che devono essere restituiti in output perché questi vengono selezionati dal servizio che esegue la FUN.

La risoluzione delle variabili

All’interno della FUN di TOOLTIP1 è stato utilizzato un placeholder (segnaposto) tra parentesi graffe. La variabile {ID_LI} è l’id del collaboratore che viene restituito dalla prima FUN. Questo viene sostituito a runtime ed utilizzato per leggere i dati della sede.

F(EXB;WESER_23;MAT.PRI) 1(CN;COL;{ID_LI})

Allo stesso modo, all’interno della FUN di LISTA CLIENTI, la variabile {U/011} corrisponde all’id della sede che viene restituita da TOOLTIP1 ed utilizzata per leggere e fornire i dati della sede.

F(EXB;LOA10_SE;ELE) 1(LI;CNCLI;*) INPUT(Sch(S/DFT) SchPar() NTit(1) ChL(1) Opz(No) NK01(1) FSA(SEDE = {U/011} ,) RPa(00100)   Flt(S)  Refresh(1) )

Riassumendo, l’aggregator usa dei placeholder (che vengono sostituiti a runtime) per formare le chiavi di unione all’interno delle relazioni, così da permettere di eseguire delle operazioni di lettura nidificate.

Le REST API e le actions in breve

Il primo utilizzo dell’aggregator è stato all’interno delle REST API di Smeup, vediamo quindi brevemente la struttura e quella delle Actions.

Le REST API di Smeup sono state introdotte in tempi relativamente recenti ed hanno riscosso molto successo. Il loro obiettivo è quello di permettere, a chiunque abbia le autorizzazioni, di accedere ai dati di Smeup eseguendo delle semplici chiamate HTTP. Proprio per questo motivo sono stati sviluppati degli endpoint specifici che hanno preso il nome di “Actions“.

In sostanza, ogni Action esegue “un’azione” che viene definita nel gestionale ed è collegata ad una FUN. Quest’ultima eseguirà delle operazioni sul database e restituirà infine i corrispondenti dati. Nel nostro caso, è stata definita l’azione “LEVELS” la cui definizione è stata già mostrata nella prima parte di questo articolo. Trattandosi di un nuovo sviluppo, quest’azione deve essere definita localmente (dove vengono installate le REST API) nel file “smeup.actions” e non su AS400.

È stata messa a disposizione un’installazione di test per dimostrarne il funzionamento.

Screenshot dell'installazione di test delle Smeup Rest Api

Tra i vari metodi delle REST API è possibile trovare:

  • /actions: restituisce le definizioni di tutte le azioni disponibili;
  • /action: restituisce la definizione di una singola azione;
  • /runAction: esegue un’azione;
  • /reloadAction: ricarica l’elenco delle azioni nel caso sia stato modificato.

L’esecuzione di un’azione (runAction) permette di ricevere i dati.

Action in action

Per dimostrarne concretamente il funzionamento, eseguiamo l’azione “LEVELS”.

Esempio di funzionamento dello Smeup Data Aggregator

Le Action delle REST API restituiscono i dati in formato JSON, che si adatta particolarmente a questa struttura gerarchica dei dati. Cliccando qui è possibile scaricarne un esempio

Con questo esempio, abbiamo dimostrato come è possibile estrarre i dati in modo molto dinamico semplicemente utilizzando un file JSON in cui viene iniettato un DSL di Smeup.