In diesem Blog Posting möchte ich mich den Oracle Rest Data Services (ORDS) widmen. ORDS hat seine Ursprünge im APEX Listener, dem javabasierten Webserver für Application Express. Dieser wurde Stück für Stück um Funktionen zum Bereitstellen von REST-Webservices erweitert - und in diesem Zusammenhang wurde der Name von "APEX Listener" auf "Oracle Rest Data Services geändert". ORDS bietet folgende Funktionen an.
- Webserver für Application Express
- REST-Endpoint für relationale Tabellen und Views
- REST-Endpoint für PL/SQL Funktionen, Prozeduren und anonyme Blöcke
- REST-Endpoint für die JSON-Funktionen in der Oracle Datenbank 12c (SODA)
- REST-Endpoint für die Oracle NoSQL DB
Man sieht, dass der Namenswechsel hin zum Thema "REST" absolut gerechtfertigt ist; "APEX Listener"
würde den Möglichkeiten nicht wirklich gerecht werden. Im ersten Blog-Posting zu ORDS möchte ich
den zweiten Punkt herausgreifen: ORDS bietet wirklich sehr schöne Möglichkeiten an, mit sehr wenig
Aufwand REST-Endpoints für Tabellen und Views in einem Datenbankschema bereitzustellen.
Ladet euch ORDS zunächst herunter und packt das ZIP-Archiv aus. Haltet euch Verbindungdaten
zur Datenbank, mit der Ihr arbeiten möchtet bereit - Ihr müsst euch als SYS anmelden.
Für das heutige Blog Posting muss es nicht zwingend eine 12c-Datenbank sein, eine 11g tut es auch.
Nach dem Herunterladen und Auspacken solltet Ihr einen Ordner mit folgenden Dateien haben.
O:\>dir Volume in drive O is Data Volume Serial Number is 5054-5D26 Directory of O:\ 24.06.2015 15:34 <DIR> . 24.06.2015 15:34 <DIR> .. 24.06.2015 15:15 <DIR> docs 24.06.2015 15:15 <DIR> examples 12.05.2015 17:04 46.105.880 ords.war 01.05.2015 10:28 23.806 readme.html 2 File(s) 46.129.686 bytes 4 Dir(s) 195.599.679.488 bytes free
Nun geht es daran, ORDS erstmalig zu starten - ORDS wird dabei ein Metadaten-Schema in die
Datenbank installieren, denn die Definitionen der REST-Services werden in der Datenbank gespeichert.
Startet die Installation also mit java -jar ords.war install.
Der Installer fragt euch nun nach den Angaben zur Datenbank, also Hostnamen, Listener Port, Service Name
und schließlich auch das DBA-Password - das wird zur Installation des Metadaten-Schemas gebraucht.
O:\>java -jar ords.war install Enter the name of the database server [localhost]:sccloud034 Enter the database listen port [1521]:1521 Enter 1 to specify the database service name, or 2 to specify the database SID [1]:1 Enter the database service name:pdb01.de.oracle.com Enter 1 if you want to verify/install Oracle REST Data Services schema or 2 to skip this step [1]:1 Enter the database password for ORDS_PUBLIC_USER:****** Confirm password:****** Please login with SYSDBA privileges to verify Oracle REST Data Services schema. Installation may be required. Enter the username with SYSDBA privileges to verify the installation [SYS]:SYS Enter the database password for SYS:****** Confirm password:****** Jun 24, 2015 3:42:57 PM oracle.dbtools.rt.config.setup.SchemaSetup addSchemaParams INFO: Oracle REST Data Services schema does not exist and will be created. Enter the default tablespace for ORDS_METADATA [SYSAUX]:SYSAUX Enter the temporary tablespace for ORDS_METADATA [TEMP]:TEMP Enter the default tablespace for ORDS_PUBLIC_USER [USERS]:USERS Enter the temporary tablespace for ORDS_PUBLIC_USER [TEMP]:TEMP :
Danach geht es mit einer Frage zum APEX Listener weiter - diese ist nur interessant, wenn
der ORDS gleichzeitig als APEX-Webserver dienen soll. Das steht heute nicht im Mittelpunkt,
daher könnt Ihr den Punkt überspringen.
Enter 1 if you want to use PL/SQL Gateway or 2 to skip this step [1]:2 Enter 1 to specify passwords for Application Express RESTful Services database users (APEX_LISTENER, APEX_REST_PUBLIC_USER) or 2 to skip this step [1]:2
Dann seht Ihr einige Statusmeldungen ...
Jun 24, 2015 3:43:04 PM oracle.dbtools.common.config.file.ConfigurationFilesBase update INFO: Updated configurations: defaults, apex_pu Jun 24, 2015 3:43:04 PM oracle.dbtools.installer.Installer installORDS INFO: Installing Oracle REST Data Services version 3.0.0.121.10.23 ... Log file written to C:\Users\cczarski\ordsinstall_2015-06-24_154305_00043.log ... Verified database prerequisites ... Created Oracle REST Data Services schema ... Granted privileges to Oracle REST Data Services ... Created Oracle REST Data Services database objects ... Created Oracle REST Data Services proxy user Jun 24, 2015 3:43:50 PM oracle.dbtools.installer.Installer installORDS INFO: Completed installation for Oracle REST Data Services version 3.0.0.121.10.23. Elapsed time: 00:00:45.343
Zum Abschluß kommt noch die Frage, ob ORDS im Standalone Modus starten soll oder ob Ihr diesen in einen
Java-Server wie Weblogic oder Tomcat deployen wollt. Für heute reicht uns der Standalone-Modus aus;
den HTTP-Port, nach dem er uns dann fragen wird, legen wir mit 8081 fest.
Enter 1 if you wish to start in standalone mode or 2 to exit [1]:1 Enter the HTTP port [8080]:8081
Soweit ist die Installation fertig; die letzte Statusmeldung sagt euch, dass ORDS jetzt läuft.
: Jun 24, 2015 3:46:35 PM oracle.dbtools.common.config.db.DatabasePools validatePool INFO: Pool: apex_pu is correctly configured 2015-06-24 15:46:35.505:INFO:/ords:main: INFO: Oracle REST Data Services initialized|Oracle REST Data Services version : 3.0.0.121.10.23|Oracle REST Data Services server info: jetty/9.2.z-SNAPSHOT| 2015-06-24 15:46:35.508:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@4bb4de6a{/ords,null,AVAILA BLE} 2015-06-24 15:46:35.588:INFO:oejs.ServerConnector:main: Started ServerConnector@17c386de{HTTP/1.1}{0.0.0.0:8081} 2015-06-24 15:46:35.589:INFO:oejs.Server:main: Started @307536ms
Doch was macht man damit? Wenn man nun die URL {hostname}:8081/ords aufruft, passiert noch
gar nichts: Es gibt eine HTTP-404-Fehlermeldung (Not Found) und weiter sieht man nichts.
Grund ist, dass noch keine REST-Services definiert wurden. ORDS bringt dafür keine Web-Oberfläche
mit, vielmehr kann man die REST-Services mit dem Oracle SQL Developer oder auf dem SQL-Prompt
mit PL/SQL Calls einrichten. Für dieses Blog-Posting nehmen wir letzteren Ansatz. Verbindet euch also
(mit dem SQL-Werkzeug eurer Wahl) auf das Schema SCOTT in der Datenbank, die Ihr beim Installieren
von ORDS angegeben habt. Schaut euch darin das PL/SQL Paket ORDS an.
SQL> sho user USER ist "SCOTT" SQL> desc ords PROCEDURE CREATE_PRIVILEGE Argument Name Typ In/Out Defaultwert? ------------------------------ ----------------------- ------ -------- P_NAME VARCHAR2 IN P_ROLES TABLE OF VARCHAR2(32000) IN P_LABEL VARCHAR2 IN DEFAULT P_DESCRIPTION VARCHAR2 IN DEFAULT PROCEDURE CREATE_PRIVILEGE Argument Name Typ In/Out Defaultwert? ------------------------------ ----------------------- ------ -------- P_NAME VARCHAR2 IN P_ROLE_NAME VARCHAR2 IN P_LABEL VARCHAR2 IN DEFAULT P_DESCRIPTION VARCHAR2 IN DEFAULT PROCEDURE CREATE_PRIVILEGE_MAPPING Argument Name Typ In/Out Defaultwert? ------------------------------ ----------------------- ------ -------- P_PRIVILEGE_NAME VARCHAR2 IN P_PATTERNS TABLE OF VARCHAR2(32000) IN :
Besonders interessant sind die Prozeduren ENABLE_SCHEMA und ENABLE_OBJECT. Diese machen das Auto-Rest Feature aus, mit dem sich in wenigen Handgriffen ein REST-Endpoint für eine Tabelle erstellen lässt. Und das machen wir nun. Zuerst müssen wir REST grundsätzlich für das Schema SCOTT freischalten.
begin ords.enable_schema ( P_ENABLED => true, P_SCHEMA => 'SCOTT', P_AUTO_REST_AUTH => false ); end; / sho err
Die Benutzung von ENABLE_SCHEMA ist wirklich einfach. Der erste Parameter (P_ENABLED) legt fest, ob
das Schema freigegeben oder gesperrt sein soll; danach kommt das Schema selbst (P_SCHEMA). Der letzte Parameter
P_AUTO_REST_AUTH legt fest, ob sich ein REST-Client authentizieren muss, wenn er die REST-Endpoints
verwenden möchte. Der Default ist true, was das Sicherheitslevel etwas erhöht. Für unsere
Tests setzen wir es jedoch auf false; Authentifizierung bleibt in diesem Blog-Posting zunächst
außen vor. Setzt noch ein COMMIT ab; wir sind ja in der Datenbank.
Allerdings steht nun immer noch kein REST-Endpoint bereit, denn wir haben noch keine Tabellen
oder Views freigegeben. Das kommt jetzt - mit einem Aufruf von ENABLE_OBJECT.
begin ords.enable_object ( P_ENABLED => true, P_SCHEMA => 'SCOTT', P_OBJECT => 'EMP', P_OBJECT_TYPE => 'TABLE', P_OBJECT_ALIAS => 'the-emp-table', P_AUTO_REST_AUTH => false ); end; / sho err
Die Parameter P_ENABLED, P_SCHEMA und P_AUTO_REST_AUTH haben die gleiche Bedeutung
wie bei ENABLE_SCHEMA. Zusätzlich muss man hier natürlich noch den Namen der Tabelle oder View
(P_OBJECT) und (optional) einen URL-Alias (P_OBJECT_ALIAS) angeben. Nach dem obligatorischen COMMIT steht ein REST-Endpoint für die Tabelle EMP unter der URL
/ords/scott/the-emp-table bereit. Probiert es aus, und ruft die URL mit dem Browser
auf - ihr solltet die Inhalte der Tabelle EMP im JSON-Format sehen.

Stellt nun sicher, dass die Spalte EMPNO der Tabelle EMP als Primärschlüssel definiert ist; oft
ist das nicht der Fall.
SQL> alter table EMP add constraint PK_EMP primary key (EMPNO);
Jetzt könnt Ihr per URL auch einzelne Zeilen ansteuern; während die URL /ords/scott/the-emp-table
alle Zeilen der Tabelle zurückliefert, liefert die URL /ords/scott/the-emp-table/7839 nur die eine Zeile mit der EMPNO 7839 zurück. Darüber hinaus unterstützt ORDS auch eine
"JSON-Query"-Syntax. Probiert mal folgende URLs aus:
- /ords/scott/the-emp-table/?q={"sal":{"$lt":1000}}
- /ords/scott/the-emp-table/?q={"ename":{"$like":"S%25"}}
- /ords/scott/the-emp-table/?q={"ename":{"$eq":"KING"}}
Die komplette Beschreibung der Query-Syntax findet Ihr in der Dokumentation. Zum Lesen der Tabelle gibt es also schon eine sehr
elegante REST-Schnittstelle - aber ORDS kann noch mehr.
Setzt man anstelle des HTTP-GET-Requests einen PUT, POST oder DELETE-Request ab, so können die Inhalte
der Tabelle auch verändert werden. Hierzu reicht der einfache Browser aber nicht aus; Ihr braucht einen
REST-Client. Diese sind auch als Browser-Plugins erhältlich - so gibt es für Chrome die
App Advanced REST Client;
für Firefox ist das Addon REST-Client verfügbar und als
Standalone-Anwendung kommen Kandidaten wie Postman
in Frage. Das folgende Bild zeigt die Chrome-App Advanced REST Client.

Nun wollen wir per REST-Request eine Zeile in die Tabelle einfügen. Macht im Chrome Advanced Rest Client
folgende Angaben (andere REST-Clients sehen ähnlich aus).
- Legt PUT als Request-Type fest.
- Als URL legt Ihr /ords/scott/the-emp-table/8999 fest; hier geben wir den Wert für die EMPNO schon in der URL an, weil die Tabelle EMP keine Sequence und keinen Trigger hat, um die ID automatisch zu generieren. Wenn Ihr eine Tabelle hat, deren Primary Key-Spalte automatisch generiert wird, könnt Ihr zum Einfügen einer Zeile einfach einen POST-Request an die URL der Tabelle (hier: /ords/scott/the-emp-table/) absetzen.
- Als Payload oder Request Body tragt Ihr die Daten der neuen Zeile im JSON-Format ein, also wie folgt:
{"empno": 8999, "ename": "CZARSKI", "job": "BLOGGER", "sal": 0, "comm": 0, "mgr": 7839, "deptno": 30}
- Achtet schließlich darauf, dass der HTTP-Header Content-Type auf application/json gesetzt ist; bei der Chrome-App ist das der Default; anderswo muss man es explizit einstellen.
Wenn Ihr den Request dann absendet, bekommt Ihr eine Antwort, welche nochmals die neue Zeile im JSON-Format
enthält. Eine Prüfung der Tabelle EMP im SQL-Tool zeigt euch, dass tatsächlich eine Zeile
eingefügt wurde.

SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- --------- ----- ------------------- ----- ----- ------ 7369 SMITH CLERK 7902 17.12.1980 00:00:00 800 20 7499 ALLEN SALESMAN 7698 20.02.1981 00:00:00 1600 300 30 : 7934 MILLER CLERK 7782 23.01.1982 00:00:00 1300 10 8999 CZARSKI BLOGGER 7839 0 0 30
Ein erneutes HTTP-PUT auf die gleiche URL (mit der 8999) führt zu einem Update der Zeile.
Um sie zu löschen, braucht
es einen DELETE-Request.
- Legt DELETE als Request-Type fest.
- Als URL legt Ihr /ords/scott/the-emp-table/8999 fest.
- Als Payload oder Request Body tragt Ihr nichts ein
- Stellt sicher, dass der HTTP-Header Content-Type nun auf text/plain gesetzt ist; wenn er noch auf application/json steht, müsst Ihr ihn umstellen.
Ihr solltet die Antwort bekommen, dass eine Zeile gelöscht wurde; eine Kontrolle der EMP-Tabelle
sollte dann ergeben, dass die neue Zeile tatsächlich weg ist. Für DELETE-Requests könnt Ihr auch die
JSON-Query-Syntax verwenden, die weiter oben bei den GET-Requests beschrieben wurde. Diese Syntax
erlaubt euch auch, mehrere Zeilen auf einmal zu löschen.
Für heute soll das mal genügen; allerdings
haben wir nur ein wenig an der Oberfläche der neuen Möglichkeiten gekratzt; ORDS erlaubt auch das
Erstellen von REST-Services mit eigenen SQL-Queries oder PL/SQL-Objekten - dazu jedoch mehr in späteren
Blog-Postings - bis dahin viel Spaß beim Ausprobieren ...