Nel 2010, quando la tecnologia dietro ai microservizi era ancora un argomento per addetti ai lavori e le aziende erano alle prime armi con le implementazioni di architetture SOA utilizzando i web services, Oracle introduceva in APEX una funzionalità che poi è diventata quello che oggi è più comunemente conosciuto come Oracle REST Data Services (ORDS), ossia uno strumento che permette di esporre i dati presenti nel database utilizzando API REST senza la necessità di sviluppare codice.
Successivamente, nel 2014, la release 12.1 di Oracle Database ha esteso ORDS introducendo Simple Oracle Document Access (SODA), uno strumento che permette di creare e archiviare raccolte di documenti (oggetti JSON) nel database Oracle, permettendo di recuperarli e interrogarli via REST in maniera indipendente dalla modalità con cui i dati vengono archiviati nel database.
Oracle APEX è integrato con entrambe queste due tecnologie e in questo articolo desidero spiegarti come costruire in pochi minuti una interfaccia REST che ti permetta, ad esempio, di connettere una applicazione Oracle APEX alla tua piattaforma IOT, al tuo e-commerce oppure al tuo CRM in cloud.
IN QUESTO ARTICOLO
Come funziona Oracle REST Data Services
ORDS fornisce strumenti per la generazione di API REST che accedono a singole tabelle e viste producendo in output documenti in formato JSON.
E’ possibile eseguire semplici statement SQL, stored procedures o query SQL più complesse, eseguendo automaticamente il mapping dei dati sia in ingresso che in uscita.
Quella che ho riportato qui sotto è un semplice schema di iterazione tra un client (a sinistra) e il database Oracle (a destra).

Il client, chiamando un URI, esegue un comando REST che viene interpretato da ORDS con uno specifico comando SQL (Map & Bind).
Il mapping tra i verbi REST e le operazioni che esegue il database sono riportate nella seguente tabella:
Comando REST | Comando SQL |
---|---|
GET | SELECT |
POST | INSERT |
PUT | UPDATE |
DELETE | DELETE |
Il database esegue il comando (ad esempio una query SELECT) e restituisce ad ORDS l’elenco delle righe in formato JSON.
Prima di iniziare
Quando lavori con i web services, è utile avere a disposizione degli strumenti che possano simulare le chiamate che un sistema deve fare per interrogare un servizio specifico.
Uno dei più famosi tool disponibili per testare i web services è SoapUI, di cui puoi scaricare la versione open source a questo link.

Attivare i servizi ORDS RESTful Data Services
Prima di iniziare a costruire servizi REST all’interno di APEX, è necessario attivare i servizi ORDS. Non spaventarti, è una procedura più facile di quello che sembra e non avrai bisogno di un DBA per eseguirla.
- Collegati al Workspace APEX
- Clicca su SQL Workshop > RESTful Services

- Se i servizi RESTful non sono stati attivati in precedenza (in tal caso non devi fare nulla), dovresti vedere questo messaggio: Schema not registered with ORDS

- Per attivare ORDS premi sul pulsante Register Schema with ORDS
- Lascia i parametri di default e premi Save Schema Attributes

- La procedura dovrebbe completarsi abbastanza velocemente con questo messaggio di conferma

Panoramica della console ORDS RESTful Services
Dopo aver attivato ORDS puoi finalmente iniziare a creare le tue API REST, tuttavia vale la pena spendere un paio di parole su come muoversi all’interno di questo ambiente di sviluppo.

A sinistra dovresti vedere il repository di tutti gli oggetti che andrai a manipolare. Le tre categorie principali sono:
- Modules: rappresentano dei contenitori logici all’interno dei quali andremo ad implementare i vari servizi REST che desideriamo esporre.
- Privileges: permettono di controllare l’accesso ai moduli REST. Per proteggere un modulo REST, ovvero per far si che non possa essere invocato da chiunque, devi prima di tutto assegnarlo ad un privilegio. Dopo aver assegnato un modulo ad un privilegio, solo gli utenti che hanno quel privilegio possono usare i servizi di quel modulo. Per assegnare uno o più privilegi ad un utente si usano i ruoli.
- Roles: per far si che uno specifico modulo REST possa essere utilizzato solo da specifici utenti, dovrai creare un ruolo che abbia un privilegio sul modulo ed infine assegnare il ruolo all’utente.

Vedremo meglio come creare Privilegi e Ruoli più avanti. Per il momento concentriamoci sul nodo Moduli.
Se lo espandi, dovresti trovare un esempio (oracle.example.hr) che puoi usare per fare qualche test. Cliccando sul modulo dovresti vedere tutti i servizi che espone.

Ciascun servizio presente all’interno di un modulo può implementare uno o più metodi tra quelli previsti dallo standard REST. Ad esempio il servizio employees/:id implementa 2 metodi:
- GET: recupera le informazioni di un record
- PUT: aggiorna i campi di un record

Cliccando con il mouse su un qualsiasi nodo dell’albero, puoi controllare e modificarne le proprietà. Ad esempio, puoi vedere come è stato implementato il metodo GET del servizio employees/:id.
Nella schermata a destra potrai vedere tutte le sue caratteristiche. In particolare:
- Full URL: l’URL del servizio. In questo punto puoi dichiarare eventuali parametri (es.: id)
- Method: il tipo di metodo REST implementato, tra quelli previsti dallo standard (GET, PUT, DELETE, POST)
- Source Type: il tipo di operazione che il database deve eseguire quando viene invocato il servizio.
- Source: il codice SQL da eseguire.
Ad esempio è stato implementato un metodo GET che accetta in input un parametro chiamato :id e si occupa di eseguire una query che restituisce un record (Query One Row).

In questo secondo esempio, invece, è stato implementato un metodo PUT di tipo PL-SQL. Ti faccio notare che in questo caso nel campo Source è stato inserito un blocco PL-SQL.

Come creare un servizio REST di tipo GET
Il primo esercizio che faremo è molto semplice. Creiamo una api REST che si occupa di restituire tutti i record di una tabella.
Se vuoi puoi utilizzare questa tabella con dati che ho preparato appositamente per questo tutorial.
- Accedi alla console RESTful e clicca su Moduli
- Clicca Create Module

- Inserisci le informazioni richieste

- Ecco una spiegazione dei campi:
- Module Name: nome del modulo RESTful. Deve essere univoco.
- Base Path: è una stringa case sensitive utilizzata per accedere al servizio RESTful. Il Base Path viene utilizzato per costruire l’URI del servizio e deve essere univoco all’interno dello schema.
- Full URL: è l’URL del modulo.
- Is Published: flag che permette di attivare o disattivare il modulo REST
- Pagination Size: numero di record restituiti da una chiamata singola
Questa è la struttura dell’URL di un servizio

Una volta creato il modulo REST possiamo precedere con la creazione dei singoli servizi.
- Per far questo, dalla schermata del modulo premi Create Template

- Specifica nel campo URI Template il nome del servizio (e quindi l’URI per invocarlo) e clicca su Create Template.

L’ultima cosa da fare consiste nel creare un Handler, ossia specificare quali e quante operazioni l’api può eseguire.
- Clicca su Create Handler

- Specifica il metodo REST da implementare (GET) e il tipo di sorgente (Collection Query)
- Nel campo Source scrivi la query che il database deve eseguire

Bene, hai creato il tuo primo Web Service REST. Puoi provarlo subito!
- Copia la stringa che trovi nel campo Full URL.
- Apri un browser web ed inserisci la stringa URL.
- Questo è il risultato che dovresti ottenere.

Come inserire un parametro in una API REST
L’esempio che abbiamo fatto non prevede parametri in ingresso alla chiamata.
Se ci penso questo ha senso perché volevamo implementare un servizio che restituisse tutto il contenuto di una tabella (o in generale di una query)
Tuttavia, nella realtà, molti microservizi hanno bisogno di parametri in ingresso per poter funzionare.
Supponiamo, a tal proposito, di voler implementare un servizio che restituisce i dettagli di uno specifico record della nostra tabella.
Pertanto il flusso logico delle operazioni dovrebbe essere questo:
- Il client invoca il servizio passando come parametro l’id del record
- Il servizio restituisce il record con i suddetti dettagli
Mettiamoci all’opera!
- Clicca su Modules

- Clicca su Create Template
- Come visto prima, inserisci nel campo URI Template il nome del servizio che vuoi creare seguito da “/:id”
- Premi Create Template.

- Clicca Create Handler

- Specifica le varie proprietà dell’handler come fatto nell’esempio precedente. L’unica differenza sarà la query da inserire nel campo Source che dovrà contenere la condizione sul campo ID.

- Per testare il servizio, copia l’URL e sostituisci al posto della string :id, l’id del record che desideri recuperare.
- Dopo aver inserito il link in un browser web dovresti ottenere questo è il risultato

Come creare un servizio REST di tipo PUT
Oltre al già visto metodo GET, il protocollo REST mette a disposizione altri 3 metodi: POST, DELETE e PUT.
Vediamo come implementare una operazione PUT. A tal proposito estenderemo il template employee/:id che abbiamo creato pochi minuti fa.
- Seleziona il template employee/:id

- Clicca Create Handler

- Inserisci le seguenti opzioni:
- Method: PUT
- Source Type: seleziona l’opzione PL/SQL.
- MIME Types Allowed: lascia vuoto
- Requires Secure Access: seleziona No
- Source: inserisci il seguente codice PL-SQL
begin
update table_demo_employee
set first_name = :first_name,
last_name = :last_name,
job = :job,
hire_date = :hire_date,
salary = :salary,
department = :department
where id = :id;
:status := 200;
:location := :id;
exception
when others then
:status := 400;
end;
- Clicca Create Handler

- Sempre dalla pagina di definizione dell’handler, vai alla sezione Parameters e clicca su Add Row

- Inserisci un primo record con i seguenti valori
- Name: ID
- Bind Variable Name: id
- Access Method: IN
- Source Type: HTTP HEADER
- Parameter Type: STRING
- Inserisci un secondo record con i seguenti valori
- Name: X-APEX-FORWARD
- Bind Variable Name: location
- Access Method: OUT
- Source Type: HTTP HEADER
- Parameter Type: STRING
- Inserisci un terzo record con i seguenti valori
- Name: X-APEX-STATUS-CODE
- Bind Variable Name: status
- Access Method: OUT
- Source Type: HTTP HEADER
- Parameter Type: INTEGER

Come testare l’API REST usando SoapUI
A differenza di quanto abbiamo visto per il metodo GET, per testare un metodo PUT, come quello che abbiamo creato adesso, non basta usare il browser.
Dobbiamo usare un client in grado di eseguire una chiamata di tipo PUT.
SoapUI è esattamente lo strumento che fa al caso nostro.
- Avvia SoapUI
- Clicca Create new REST Project

- Inserisci l’URI del servizio REST

- Seleziona il metodo GET e premi Esegui. Nella finestra a sinistra dovresti vedere la risposta nel formato JSON

- Ora cambia il metodo da GET a PUT

- Inserisci il payload della chiamata REST specificando i nuovi valori che vuoi salvare nel database
{
"id": 1,
"first_name": "demo first_name_new",
"last_name": "demo firstname_name_new",
"job": "demo job_name_new",
"hire_date": "01/01/2021",
"salary": "0",
"department": "demo department_new"
}
- Premi Esegui

- A destra, nella finestra della Response, dovresti vedere i dati aggiornati e l’esito della chiamata (status = 200)

- Lo stato restituito dalla chiamata è esattamente quello che abbiamo specificato nel blocco PL-SQL dell’handler PUT

Come implementare l’autenticazione
Quando si costruiscono API REST è buona norma implementare un meccanismo di autenticazione che ne impedisca l’accesso o utilizzo non autorizzato.
Fortunatamente, Oracle APEX fornisce diversi meccanismi di sicurezza. Il primo e più facile da implementare è l’autenticazione (Basic Authentication).
Vediamo un modo per implementare questo tipo di autenticazione.
Crea un ruolo
- Accedi ad Oracle APEX e vai in SQL Workshop > RESTful Services

- Seleziona il nodo Roles. Qui puoi vedere diversi ruoli, molti dei quali generati automaticamente da APEX.
- Clicca Create Role e inserisci un nuovo ruolo che si chiamerà oracle.dbtools.role.autorest.<WORKSPACE>.EMPLOYEE

Crea un privilegio
- Seleziona il nodo Privileges.

- Clicca Create Privilege ed inserisci le seguenti informazioni
- Name: oracle.dbtools.autorest.privilege.<WORKSPACE>.EMPLOYEE
- Title: employee

- Vai alla sezione Roles ad assegna a questo privilegio il ruolo che abbiamo creato allo step precedente.

- Vai alla sezione Protected Modules ed assegna il modulo REST che stiamo creando in questo momento.

Per controllare che tu stia facendo le cose corrette puoi provare a chiamare uno dei servizi che hai creato. Dovresti ottenere questo risultato

Se anche tu hai ottenuto lo stesso risultato significa che sei sulla buona strada.
Configura l’autenticazione base
- Dalla barra degli strumenti di APEX, clicca su Administration > Manage Users and Groups.

- Clicca su Groups > Create User Group

- Questo passaggio è molto importante: assegna a questo gruppo un nome identico a quello del ruolo che hai creato nell’ambiente di sviluppo REST. Ad esempio, io avevo chiamato il ruolo così: oracle.dbtools.role.autorest.APPIN5MINUTI.EMPLOYEE

- Clicca su Administration > Manage Users and Groups e vai nella scheda Users.
- Crea un nuovo utente APEX oppure apri la definizione di un utente già esistente
- Vai nella sezione Group Assignment ed assegna all’utente il gruppo che abbiamo creato.

Esegui un test
- Inserisci nel browser l’URL del servizio REST. Clicca su Sign In.

- Inserisci Username e Password dell’utente che hai creato. Premi Collega

- Il servizio è stato invocato e possiamo vedere la risposta

- Se, d’altro canto, inserisci credenziali sbagliate, dovresti ottenere il seguente messaggio di errore

Conclusioni
In questo articolo abbiamo visto come creare un servizio REST usando Oracle APEX.
Ti ho spiegato anche come implementare un livello minimo di sicurezza basato su un meccanismo di autenticazione base. Le release di APEX più recenti consentono di implementare meccanismi di sicurezza più sofisticati, basati sul protocollo OAuth 2.0.
Che tu sia una startup che ha bisogno di creare velocemente API pubbliche semplici, sicure e scalabili con il minimo sforzo oppure un’azienda più strutturata che ha bisogno di una soluzione applicativa altamente personalizzabile e semplice da integrare, Oracle APEX è sicuramente un buona scelta.
Fammi sapere cosa ne pensi!
Un abbraccio
Daniele
Articolo molto interessante. Grazie perchè è spiegato molto bene. Vorrei chiederti se riesci a rispondere ad un problema che sto affrontando nella realizzazione di servizi REST in Oracle Apex. Grazie al tuo articolo mi è chiaro come realizzarli, indicando direttamente nel campo “source” il codice PLSQL. Ma se volessi passare il riferimento di un package che richiama una determinata procedura oppure una funzione, come mi devo comportare?
Ho questa situazione:
1) in sql developer ho connessione allo schema X con un package con codice PLSQL;
2) in APEX ho definito lo schema X e vorrei richiamare il package e una determinata procedura nell’handler.
Come posso fare questo? E’ possibile questa configurazione?
Spero che qualcuno mi potrà aiutare. Grazie
Ciao Davide,
grazie per i complimenti.
La risposta è si. Di fatto puoi inserire nell’handler tutto il codice PL-SQL che vuoi.
In particolare ti consiglio di fare così:
a) crei il tuo package PLSQL con la procedura che effettua le operazioni sul database.
b) la tua procedura avrà parametri in input (IN) ed in output (OUT) che userai rispettivamente per passare i parametri necessari ad eseguire il codice e restituire l’esito in output
c) qualora dallo schema APEX non riesci ad eseguire la store procedure ricordati di assegnare i grants e EXECUTE sul package all’utente dello schema APEX
Se hai qualche dubbio su come lavorare in PL-SQL ti consiglio questa guida: https://appin5minuti.it/programmare-plsql-guida-per-principianti/
ciao
Daniele
Ciao mi sei sembrato molto chiaro. Guida utilissima. Vediamo se puoi aiutarmi. Io ho il problema di avere già un’istanza Oracle 12c, in ambiente di produzione su cui sono stato incaricato di creare con Apex dei report. Preciso che Apex non l’ho mai usato a tale scopo ma mi “gasa” provarlo ed imparare. Quello che non ho capito, dato che non si tratta di un motore Oracle in cloud (la tua guida si riferisce ad un’istanza in cloud), quali passi devo eseguire: 1) installare un motore Apex sullo stesso data server sul di produzione che ho già (ridondato su due nodi, peraltro), in versione “client”: 2) Potrei usare una istanza in cloud di Apex e farla puntare al mio ambiente di produzione (ammesso che le policy me lo consentano). Come li faccio colloquiare? 3) Oppure esistono altre strade (tipo che non si può fare con semplicità)?
Grazie moltissimo.
Ciao Fabio
Grazie per l’apprezzamento.
Nel tuo caso, visto che hai un database on-premise, il mio consiglio è quello di installare APEX come servizio della tua istanza di database.
Fai riferimento alla guida ufficiale
Questa, ad esempio, è per la versione 21.1 di Apex:
https://docs.oracle.com/en/database/oracle/application-express/21.2/installandupgrade.html
Non esistono differenze sostanziali in termini di funzionalità tra la versione disponibile su Oracle Cloud rispetto a quella On-Premise.
Ciao!
Daniele