Esempio di utilizzo delle WEB API

 

Le web api, o api rest sono un sistema di comunicazione per l'interscambio di informazioni tra sistemi web. In pratica attraverso delle richieste http è possibile interrogare e ricevere dati in un formato conosciuto da una risorsa raggiungibile via web, come ad esempio il server di sincronizzazione di Nios4.

Questo sistema permette di collegare alla piattaforma Nios4 altri programmi che potranno leggere e scrivere i dati di un database cloud direttamente,

Naturalmente, utilizzando le web api e gli script è possibile far dialogare due database di Nios4 insieme. In questo esempio vedremo come leggere e scrivere delle informazioni tra questi due database. Chiaramente il database con cui interagiremo sarà cloud, mentre quello contenente gli script per interagire può anche essere locale.

Nello specifico aggiorneremo o creeremo un articolo sul database cloud di arrivo, utilizzando uno script di post salvataggio nella scheda di quest'ultimo.

Creazione della stringa di chiamata

url = 'https://web.nios4.com/ws/?action=model' -- L'indirizzo di chiamata alle api
url = url .. '&token=' .. program.usertoken() --Il proprio token di accesso
url = url .. '&db=' .. 'DATABASE' --la matricola del database
url = url .. '&tablename=' .. 'articoli' --La tabella da leggere

Come prima cosa andremo a costruire la stringa dell'indirizzo che invieremo al server di Nios4. Infatti il collegamento non è direttamente al proprio database cloud ma passa attraverso il server.

Va inserito il nostro token di autenticazione del proprio account. In questo caso lo faremo recuperare direttamente dal sistema. In caso si volesse interagire con database di altri utenti andrà scritto il token di questi.

Va poi inserita la matricola del database, visibile all'interno dei programmi o in basso a destra o al fianco della etichetta del database.

Questi sono i parametri essenziali per ogni chiamati da eseguire verso il server, visto che identifica in modo univoco chi siamo e il database su cui agire.

Per questo specifico caso ossia l'azione model inseriremo anche il parametro tablename per indicare al sistema su quale tabella andremo ad agire.

Recupero dei valori dal server

body                   = {} 
body.conditions        = {}
body.conditions.codice = dataview.getvalue("codice") --inserisco un filtro per ricevere solo quello specifico articolo

r = program.newhttprequest()
response = r.sendpost(url, body, true)

if response.result == 'KO' then
    errorn.errorcode    = "ERRHTTP"
    errorn.errormessage =  response.error
    do return end
end

In questa fase creeremo il "payload" della chiamata, ossia la struttura dei dati che verrà spedita insieme all'indirizzo link costruito precedentemente. Creeremo il body in modo da inviare una condizione per ricevere solo degli specifici record, in questo caso il codice. "codice" è il nome del campo che deve essere prsente dentro alla tabella richiesta nella chiamata. Qui è possibile inserire anche altre condizioni, l'importante è mantenere il formato richiesto, ad esempio body.conditions.descrizione_etichetta = "etichetta"

Preparato il body creiamo l'oggetto httprequest. Questo unirà l'url della chiamata, il body e la invierà al server ricevendo la sua risposta.

In caso di errore il server risponderà con un "KO". A questo punto bloccheremo lo script e visualizzeremo l'errore ritornato.

Lettura dati ritornati


gguid    = "" --inizializzazione variabile di gguid

for key, val in pairs(response['records']) do
    
    codice_fornitore = val.codice_fornitore
    codice           = val.codice
    giacenza         = val.giacenza
    gguid            = val.gguid
    
end

Se non ci sono stati errori è possibile iniziare a leggere la risposta inviata dal server. Ricordate che il formato della risposta cambia in base alla azione richiesta. L'azione model ridà un sotto elenco records iterabile. In caso non ci siano record nella tabella, o record che non rispettano le condizioni date l'elenco sarà vuoto. Un'altra cosa da ricordare e che il server restituisce sempre dei dati in formato Json. Quindi all'interno degli script lua scrivere val.codice_fornitore o val["codice_fornitore"] è la stessa cosa. A seconda del linguaggio di programmazione usato il formato sarà letto in base alle convenzioni di quest'ultimo.

Record nuovo o da aggiornare

if gguid == "" then
   gguid = dataview.getvalue("gguid")
end

Ogni record all'interno del database viene identificato in modo univoco dal valore della colonna gguid,una stringa random di caratteri alfanumerici. In questo esempio abbiamo cercato un articolo in base al codice partendo dal concetto che esista un solo record con questo, ma è sempre il valore gguid che identifica in modo preciso un record.

Nella fase di lettura dei valori abbiamo estrapolato il valore gguid. Questo valore viene impostato solo se il server ha comunque ridato un record (potrebbero essere di più ma in questo caso diciamo che siste sempre un solo record con uno specifico codice), altrimenti rimane di valore "", ossia stringa vuota.

Se la stringa gguid è vuota significa che il server non ha dato indietro niente, quindi imposteremo noi il gguid utilizzando il valore del nostro record locale corrente.

Questo serve perchè nella prossima fase, quando invieremo i dati dell'articolo, se gli diamo un gguid presente nel database cloud, questo verrà aggiornato con i dati passati, altrimenti se non è presente verrà creato automaticamente.

La comodità di questo sistema e che la chiamata di creazione e aggiornamento è identica.

Creiamo o aggiorniamo il record sul database cloud

url       = 'https://web.nios4.com/ws/?action=table_save' -- L'indirizzo di chiamata alle api
url       = url .. '&token=' .. program.usertoken() --Il proprio token di accesso
url       = url .. '&db=' .. 'DATABASE' --la matricola del database
url       = url .. '&tablename=' .. 'articoli' --La tabella da leggere
body      = {}
body.rows = {}
body.rows[1] = {}
body.rows[1].gguid = gguid --se non presente sul server verrà creato un nuovo record
body.rows[1].codice_fornitore = dataview.getvalue("codice_fornitore")
body.rows[1].codice = dataview.getvalue("codice")
body.rows[1].descrizione = dataview.getvalue("descrizione")
body.rows[1].descrizione_alternativa = dataview.getvalue("descrizione")

r = program.newhttprequest()
response = r.sendpost(url, body, true)

if response['error'] then
    output.print(response['error_code'] .. ' - ' .. response['error_message'])
    do return end
else
    output.print('Record inserito con successo')
end

Procediamo a creare la nuova chiamata per l'invio delle informazioni. Stavolta l'azione sarà di tipo table_save. Anche in questo caso costruiremo il body da inviare creando la sotto lista rows. In questo modo possiamo inviare con una sola chiamata più record, per ogni riga rows sarà obbligatorio passare il valore gguid. Come detto se il valore esiste sul server il record verrà aggiornato, altrimenti ne verrà creato uno nuovo. Verrà creato un nuovo record anche se il valore passato è stringa vuota.

Inseriti gli altri valori desiderati invieremo la richiesta e vedremo se la risposta del server è stata positiva oppure no.

Forziamo la sincronizzazione del database cloud

url = 'https://web.nios4.com/ws/?action=sync'
url = url .. '&token=' .. program.usertoken() --Il proprio token di accesso
url = url .. '&db=' .. 'DATABASE' --la matricola del database
r = program.newhttprequest()
response = r.sendpost(url, body, true)   

Come ultimo passaggio dobbiamo richiedere al server di forzare la sincronizzazione del database cloud. Questo perchè le operazioni eseguite sono state salvate nel database ma non sono state inserite nel sistema di sincronizzazione. Inviando quest'ultima chiamata le modifiche eseguite verranno distribuite su tutti i nostri dispositivi.

Commenti