L’avvento delle applicazioni cloud-native e la diffusione sempre più pervasiva dei microservizi ha portato negli ultimi anni le API alla ribalta.
Ormai la quasi totalità delle piattaforme più famose (Google Maps, Facebook, Whatsapp, Linkedin e Amazon per citare alcuni degli esempi più famosi) mettono a disposizione degli sviluppatori numerose API che possono essere usate per sfruttare i loro servizi.
L’espressione API Economy descrive un vero e proprio modello di business basato sulle distribuzione delle API, ossia su servizi di terze parti che gli sviluppatori possono utilizzare per realizzare le proprie applicazioni.
Invece di sviluppare tutto da zero, attività molto dispendiosa, si lavora con componenti software riutilizzabili, stavolta distribuiti.
IN QUESTO ARTICOLO
Servizi API: cosa sono
Chi abbia approcciato anche un minimo lo sviluppo software sa bene che le Application Programming Interface esistono da decenni e non sono certo nate con il cloud. Per tutti gli altri, è utile familiarizzare con alcuni concetti base.
In estrema sintesi, una API delinea in che modo un qualsiasi componente software interagisce con l’esterno, quindi con altri software.
Nel caso di un microservizio, indica in che modo le sue funzioni possono essere richiamate da altri servizi o applicazioni. Come queste funzioni siano implementate resta “nascosto” a chi le richiama.
Facciamo un esempio pratico.
Vuoi creare all’interno della tua APP un modulo per postare su Twitter.
Non hai bisogno di sapere come funziona internamente la famosa piattaforma di micro-blogging.
Ti basta avere accesso alle API che Twitter mette a tua disposizione per usare tutte le funzionalità che servono per caricare un post.
Nel mondo del cloud una API è sempre basata sui protocolli tipici del web. Ciò significa in linea di principio che si interagisce con essa attraverso richieste HTTP, come un web browser, e che i dati vengono passati all’API e da essa ricevuti in formato generalmente in formato JSON (JavaScript Object Notation, un formato che per semplicità possiamo considerare analogo a XML).
Una delle conseguenze di tutto questo è che un servizio deve essere identificato da una URL a cui accedere via HTTP.
Per proseguire con il nostro esempio sull’API di Twitter, la timeline di un utente è un oggetto JSON che si “contatta” all’URL https://api.twitter.com/1.1/statuses/home_timeline.json.
Cos’è una API RESTful
La quasi totalità delle API legate allo sviluppo cloud è RESTful, un altro termine che si incontra assai di frequente.
Una API RESTful è sviluppata secondo il modello architetturale Representational State Transfer (appunto REST).
La definizione vuol dire tecnicamente molte cose, ma l’elemento che interessa di più chi vuole comprendere la dinamica dei microservizi è che questi sono a priori stateless ossia non conservano alcuna informazione riguardante l’oggetto (un’applicazione o un altro servizio) che li contatta.
Per garantire flessibilità e coerenza di funzionamento, un microservizio deve essere “agnostico” in merito a cosa lo utilizzerà.
Come richiamare una API REST in Oracle APEX
Oracle APEX supporta nativamente l’integrazione con API Rest. Questo vuol dire che puoi creare una applicazione e collegarla ad un servizio REST usando, ad esempio, del codice PL-SQL.
Con la release più recenti è inoltre possibile definire un Data Source di tipo REST che può alimentare in tempo reale un report creato in APEX. In questo caso, non hai nemmeno la necessità di scrivere codice per sarà APEX stesso a creare il connettore verso l’API Rest.
In questo tutorial vedremo entrambi i metodi.
Come richiamare una API REST usando una procedura PL-SQL
Per poter consumare un web services da codice PL-SQL all’interno della tua applicazione puoi utilizzare la libreria apex_web_service.make_rest_request.
Per fare un esempio concreto utilizzerò il servizio meteo messo a disposizione da Open Weather.
Dopo essermi registrato ed aver ricevuto una API Key (un codice alfanumerico univoco che devo utilizzare nella mia APP per interrogare il web service) posso conoscere il meteo di una qualunque località sul globo usando la seguente URL, dove andrai a sostituire la {API Key} con la chiave che hai ottenuto.
https://api.openweathermap.org/data/2.5/weather?APPID={API Key}&q=Milano,it&lang=it&units=metric
Possiamo vedere il risultato di questa chiamata inserendo l’URL direttamente nel browser.
{
"coord": {
"lon": 9.1895,
"lat": 45.4643
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "pioggia leggera",
"icon": "10d"
}
],
"base": "stations",
"main": {
"temp": 13.71,
"feels_like": 13.43,
"temp_min": 12.78,
"temp_max": 14.44,
"pressure": 1011,
"humidity": 88
},
"visibility": 8000,
"wind": {
"speed": 1.54,
"deg": 90
},
"rain": {
"1h": 0.89
},
"clouds": {
"all": 75
},
"dt": 1620720369,
"sys": {
"type": 1,
"id": 6742,
"country": "IT",
"sunrise": 1620705455,
"sunset": 1620758504
},
"timezone": 7200,
"id": 3173435,
"name": "Milano",
"cod": 200
}
Vediamo come puoi usare questo microservizio da una applicazione APEX
- Accedi all’App Builder di APEX e crea una applicazione.
- Crea una nuova pagina con questi elementi
- PX_LOCALITA: Text Field dove andremo a scrivere la località di cui vogliamo conoscere il meteo
- PX_RESPONSE: Display Text dove stamperemo la response del WS
- CHIAMA_API_REST: pulsante che servirà per lanciare la chiamata all’API

- Per testare la chiamata al web service visualizzeremo nella pagina i seguenti tag JSON:
- weather[1].description
- main.temp

- Aggiungi alla pagina i seguenti Display Text:
- PX_DESCRIPTION
- PX_TEMPERATURE

- Seleziona il pulsante CHIAMA_API_REST e crea una Dynamic Action di nome invokeAPIRest

- Aggiungi una Action di tipo Execute Server-Side Code
- Inserisci il seguente script nel corpo dell’Action PL-SQL.
- Ricordati di inserire al posto della stringa <API Key> la tua chiave di utilizzo.
declare
l_url varchar2(2000) := 'https://api.openweathermap.org/data/2.5/weather?APPID=<API Key>&q='
|| :p1_localita
|| ',it&lang=it&units=metric';
l_response clob;
begin
/* Set Content Type */
apex_web_service.g_request_headers(1).name := 'Content-Type';
/* Set Webservice Response Output */
apex_web_service.g_request_headers(1).value := 'application/json';
/* Make Webservice Request */
l_response := apex_web_service.make_rest_request(p_url => l_url, p_http_method => 'GET');
:p1_response := l_response;
end;
- Specifica i parametri di input e di output della Dynamic Action

- Prova ad eseguire l’applicazione.
- Inserisci i parametri e premi il bottone Chiama API Rest
- Nel campo Response dovresti vedere il risultato

Adesso quello che manca è estrarre dalla risposta JSON le informazioni che ci interessano utilizzando la libreria apex_json.parse
- Apri la definizione della Dynamic Action che abbiamo creato poco fa ed sostituisci lo script PL-SQL con il seguente, dove ho evidenziato le istruzioni da usare per estrarre i dati
declare
l_url varchar2(2000) := 'https://api.openweathermap.org/data/2.5/weather?APPID=<API Key>&q='
|| :p1_localita
|| ',it&lang=it&units=metric';
l_response clob;
l_description varchar2 (2000);
l_temp varchar2 (2000);
begin
/* Set Content Type */
apex_web_service.g_request_headers(1).name := 'Content-Type';
/* Set Webservice Response Output */
apex_web_service.g_request_headers(1).value := 'application/json';
/* Make Webservice Request */
l_response := apex_web_service.make_rest_request(p_url => l_url, p_http_method => 'GET');
/* Parsing Webservice Response as JSON */
apex_json.parse(l_response);
/* Get Data from Response */
l_description := apex_json.get_varchar2('weather[1].description');
l_temp := apex_json.get_varchar2('main.temp');
:p1_response := l_response;
:p1_description := l_description;
:p1_temperature := l_temp;
end;
- Se esegui la preview dell’APP dovresti ottenere il risultato seguente. Ci sei riuscito?

Considera che a questo punto puoi recuperare tutte le informazioni che vuoi dal tracciato JSON usando sempre lo stesso metodo.
Nel paragrafo successivo vedremo un modo alternativo per collegare una applicazione APEX ad un servizio Rest, molto utile soprattutto quando hai bisogno di creare dei report.
Come richiamare una API REST usando REST Data Source
Con l’avvento della release 20.2 di Oracle APEX è stata introdotta la possibilità di definire Data Source di tipo REST.
Il vantaggio per chi sviluppa APP integrate non è da poco perché è possibile configurare una connessione ad un servizio esterno (JSON o SOAP) senza dover scrivere codice.
Vediamo un modo furbo per utilizzare questa interessante funzionalità.
- Accedi all’App Builder e clicca su Shared Components

- Clicca su Data Sources > Rest Data Sources

- Da questa pagina potrai gestire tutte le connessioni REST che la tua applicazione utilizzerà. Per creare una nuova connessione REST clicca su Create

- Seleziona l’opzione From Scratch

- Inserisci le seguenti informazioni
- Rest Data Source Type: Simple HTTP
- Name: scegli un nome per la tua connessione
- URL Endpoint: inserisci l’URL da chiamare per invocare il servizio valorizzando tutti i parametri che l’API Rest richiede (nel nostro esempio la località/città di cui si vuole conoscere il meteo). Nell’applicazione finale questo parametro dovrà essere passato direttamente dall’applicazione, tuttavia per il momento non preoccupiamocene e valorizziamolo.
- Clicca Next.

- Clicca nuovamente Next

- Se il servizio che stai richiamando richiede un autenticazione puoi specificare i parametri di autenticazione in questo punto. Nel mio esempio il servizio che sto utilizzando non richiede autenticazione.
- Clicca Discover

- APEX si connette al servizio ed esegue automaticamente il mapping dei campi restituiti dal servizio REST.
- Clicca su Data Profile

- In questa schermata possiamo vedere in dettaglio come APEX ha mappato internamente i campi della Response
- In realtà, se guardiamo la risposta JSON del servizio le informazioni sono molte di più. Non preoccuparti, tra pochissimo vedremo come mappare manualmente tutti gli attributi che vogliamo utilizzare nella nostra APP
- Clicca Create REST Data Source

- L’oggetto REST Data Source è stato creato.
- Clicca sul nome per aprire il dettaglio

- Da qui puoi vedere le proprietà del connettore REST che hai creato.
- Seleziona la scheda Parameters per aggiungere e modificare i parametri

- Clicca sulla scheda Data Profile e successivamente su Edit Data Profile

- Nella sezione Data Profile, la proprietà Row Selector ti fa capire quale porzione della risposta JSON il connettore sta leggendo.

- Nel nostro caso è weather, che corrisponde a questo punto

- Dopo aver impostato il Row Selector, è possibile mappare ogni singolo campo del tracciato JSON che è incluso nel Row Selector specificato.

- Nel mio caso, purtroppo questa impostazione di default non va bene perché il Row Selector weather non include il campo temp, che è invece racchiuso nel selettore main.

Come modificare il Data Profile di una REST Data Source
Talvolta è necessario modificare il Data Profile di un connettore REST. Non spaventarti, non è complicato e con un po’ di pratica imparerai subito come fare.
- Nell’esempio che sto facendo vorrei definire per il servizio meteo un unico connettore che recuperi dalla Response JSON i seguenti campi:
- weather[1].description
- main.temp
- Vai nelle proprietà del connettore e rimuovi la proprietà Row Selector. In questo modo APEX effettuerà il parsing di tutta la Response JSON
- Modifica i selettori dei singoli campi indicando il path completo. Se non sai come costruire il path completo leggi qui.
- ID: weather[0].id
- ICON: weather[0].icon
- MAIN: weather[0].main
- DESCRIPTION: weather[0].description

- Clicca Add Column per aggiungere un nuovo campo TEMPERATURE.

- Clicca su Operation > Test Operation per eseguire un test di connessione

- I dati vengono recuperati. Perfetto!

Ora che abbiamo creato il nostro connettore (senza scrivere una linea di codice..) vediamo come usarlo nella nostra applicazione.
Come usare una REST Data Source in una applicazione
Colleghiamo il connettore che abbiamo creato ad una pagina della nostra applicazione APEX.
- Dall’App Builder crea una nuova pagina di tipo Classic Report.

- Inserisci all’interno della pagina un componente di tipo Classic Report che chiamerai Sample Data (o il nome che preferisci..).

- Crea un Page Item per ogni parametro che dovrà essere passato al web service. Nel nostro caso l’unico parametro che andremo a gestire è la località.

- Seleziona il Classic Report che abbiamo creato ed apri il pannello delle proprietà dove dovrai inserire le seguenti impostazioni
- Location: REST Source.
- REST Source: Open Weather, il connettore REST che abbiamo creato qualche minuto fa.
- Page Items to Submit: specifica i Page Items dove l’utente inserirà i parametri per la chiamata al web service.

- Seleziona il nodo Parameters del Classic Report: in questo punto APEX ha automaticamente aggiunto i parametri del connettore REST prendendoli direttamente della sua definizione.

- Seleziona il parametro che si chiama “q”, che deve essere valorizzato con il nome della località della quale si vuole conoscere la situazione meteo.
- Nelle proprietà del parametro puoi andare a scegliere come valorizzarlo. Ad esempio può essere un valori costante, oppure può dipendere dal un parametro della pagina.

- Modifica le impostazioni del parametro in questo modo:
- Type: Item
- Item: PX_LOCALITA

- Completa il setup di base della pagina creando un pulsante che servirà ad invocare l’API Rest.

- Esegui la preview dell’APP.
- Inserisci il nome di una città nel campo Località e premi il bottone Chiama API Rest. Se tutto funziona correttamente dovresti vedere le informazioni restituite dal web service, formattate nel Classic Report.

Conclusioni
Lo sviluppo di applicazioni web, che grazie all’avvento di microservizi è diventato più semplice, richiedere una certa competenza nello sviluppo di integrazioni che è sempre più cruciale.
Oracle APEX da questo punto di vista aiuta moltissimo gli sviluppatori come noi, perché permette di gestire queste integrazioni in modo agevole e immediato grazie alla possibilità di configurare connessioni REST o SOAP senza dover scrivere necessariamente del codice.
Anche se riconosco il fatto che l’argomento è molto più ampio e che merita degli approfondimenti, spero che questa breve guida possa aiutarti a comprendere meglio queste tematiche, talvolta un po’ complesse, ma decisamente importanti.
Fammi sapere qual è la tua opinione!
Un abbraccio
Daniele
Ciao Daniele,
C’è un modo per controllare l’URL Apex creato quando si chiama le REST datasource? Ho dei problemi con i parametri e mi piacerebbe controllare cosa c’è che non va.
Ciao Igor,
generalmente per testare le API Rest io utilizzo strumenti come postman oppure Soap UI.
ciao
Daniele
Ciao Daniele,
lavorando con i REST datasource in APEX come hai risolto
ORA-24247: network access denied by access control list(ACL)
?
Ciao Alessandro,
in generale questo errore sta ad indicare che il database (o meglio l’utente di database che APEX usa) non è in grado richiamare la risorsa esterna perché non autorizzato.
Per risolverlo dovresti configurare l’Access Control List, cosa che dipende da l tipo di database che stai usando (se on-premise oppure in cloud)
Ad esempio, se stai usando un database on-premise con utenza SYSDBA potresti usare il seguente script
DECLARE
l_acl VARCHAR2(100) := 'acl_name.xml';
l_desc VARCHAR2(100) := 'ACL DESCRIPTION';
l_principal VARCHAR2(30) := 'USERNAME'; -- UPPERCASE
l_host VARCHAR2(100) := 'domain.com'; --host
BEGIN
dbms_network_acl_admin.create_acl(l_acl, l_desc, l_principal, TRUE, 'connect');
dbms_network_acl_admin.add_privilege(l_acl, l_principal, TRUE, 'resolve');
dbms_network_acl_admin.assign_acl(l_acl, l_host);
COMMIT;
END;
In bocca al lupo!
Daniele