Oracle released Oracle REST Data Services (ORDS) 25.2 recently, in other words it’s time for me to upgrade. The release highlights have been summarised elsewhere, so I won’t do that again. Please head over to Chris Hoina’s blog post for all the details.
One thing in particular I would like to point out though is an improvement for anyone developing REST APIs using MLE/JavaScript handlers. I wrote an article how to debug ORDS handlers written in JavaScript earlier. The article focuses on what exactly you can do in case your code throws an error leading to an exception in ORDS.
This article covers another aspect: console.log() output.
Show me a demo already!
Note that using console.log() isn’t debugging – there are better ways to do that. However sometimes it can be convenient to just print something on the console. Let’s see how you can do that with ORDS.
For reference, I used the following software on Linux x86-64
- Oracle Database 23ai Free (23.8)
- ORDS 25.2.0.r1651520
- SQLcl 25.2.
Let’s create an ORDS service to validate an email address. Rather than re-inventing the wheel a third party module from NPM – validator.js – will be used.
Please refer to validator’s GitHub project site for more details about the project’s license and implications of use. The article assumes your legal and IT Security departments (as well as any other party) agreed that it’s safe to use the module in your code. Using 3rd party code in your application typically requires certain compliance steps to be completed which are out of scope of this article.
Creating the Validator module
First of all you need to create the validator module in your database. This can be done in many ways, SQLcl, installed in /opt/oracle/sqlcl on my system, offers by far the most convenient way. Here are the steps I followed:
curl -Lo /tmp/validator.mjs 'https://cdn.jsdelivr.net/npm/validator@13.15.0/+esm'
/opt/oracle/sqlcl/bin/sql demouser@localhost/freepdb1
SQLcl: Release 25.2 Production on Thu Jul 10 12:55:20 2025
Copyright (c) 1982, 2025, Oracle. All rights reserved.
Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04
SQL> mle create-module -filename /tmp/validator.mjs -version 13.15.0 -module-name VALIDATOR_MODULE
MLE Module VALIDATOR_MODULE created
That’s step number 1 completed.
Adding the JavaScript module
With the validator module created it’s time to create the JavaScript module and environment for use in ORDS. The code is very simple – strictly speaking you could have simply imported the validator module in the ORDS handler, but it’s a better practice to separate “business” logic from the ORDS handler. In the following example the only thing the ORDS handler has to do is pass a part of the payload to the function exported in this module.
create or replace mle module demo_module language javascript as
import validator from 'validator';
/**
* Perform a simple email validation based on validator.js
*
* @param {string} emailAddress the email address to validate
* @returns object containing the result of the validation
*/
export function validateEmail(emailAddress) {
let result;
if (emailAddress === undefined || emailAddress === null) {
// this isn't a great practice: used for demonstration purposes only!
console.log('An emailAddress has not been provided at all');
result = {
statusCode: 422, // 422 Unprocessable Entity
message: "you must provide a string representing an email address"
};
} else if (validator.isEmail(emailAddress)) {
// this isn't a great practice: used for demonstration purposes only!
console.log('An emailAddress been provided and it is valid');
result = {
statusCode: 200, // 201: OK
message: `${emailAddress} is a valid email address`
}
} else {
// this isn't a great practice: used for demonstration purposes only!
console.log('An emailAddress been provided but it is NOT valid');
result = {
statusCode: 400, // 400: Bad Request
message: `${emailAddress} is NOT a valid email address`
}
}
return result;
}
/
create or replace mle env demo_env imports (
'demo' module demo_module,
'validator' module validator_module
)
/
That’s both the JavaScript module and environment created. The MLE environment is required for name resolution. The following code block imports from demo, which maps to the demo_module created earlier. The environment must also provide a mapping for the validator module.
Defining the REST API
The creation of the ORDS REST API brings it all together. The REST verb used is POST, since that’s the most generic one for data validation.
declare
c_module_name constant varchar2(255) := 'mle_demo_api';
c_pattern constant varchar2(255) := '/validate/';
begin
ords.define_module(
p_module_name => c_module_name,
p_base_path => '/api/',
p_status => 'PUBLISHED',
p_items_per_page => 25,
p_comments => 'ORDS demo showing improved console logging in release 25.2 and later'
);
ords.define_template(
p_module_name => c_module_name,
p_pattern => c_pattern,
p_priority => 0,
p_etag_type => 'HASH',
p_etag_query => null,
p_comments => 'validate an email address'
);
ords.define_handler(
p_module_name => c_module_name,
p_pattern => c_pattern,
p_method => 'POST',
p_source_type => 'mle/javascript',
p_mle_env_name => 'DEMO_ENV',
p_items_per_page => 0,
p_mimes_allowed => null,
p_comments => null,
p_source => q'~
(req, resp) => {
const { validateEmail } = await import ("demo");
const result = validateEmail(req.body.email);
resp.status(result.statusCode);
resp.content_type("application/json");
resp.json(result);
}
~'
);
end;
/
If you like to learn more about the request and response objects, please refer to the ORDS reference.
Enable console.log() output
Debug output is disabled by default which is the right thing to do for production environments. To enable it you have 2 choices:
- enable globally
- enable per schema
I went with the latter option. Jeff Smith wrote a more detailed post about the debug.printDebugToScreen setting – head over there if you like to know more. I opted for the less intrusive method of enabling the setting for my schema in my development environment. Don’t simply go ahead and turn this on in production. Again, Jeff Smith’s post has the details.
I ran the following as SYSTEM
begin
ords_admin.set_property(
p_schema => 'DEMOUSER',
p_key => 'debug.printDebugToScreen',
p_value => 'true'
);
commit;
end;
/
With the setting enabled, ORDS will print the debug information on the console:
2025-07-10T13:19:52.066Z INFO <nxQeXaeWNnImNf85tEy1Sw> [ORDS MLE]An emailAddress been provided but it is NOT valid
2025-07-10T13:19:57.185Z INFO <HZNu2UFGR94OMRpvbh6m9g> [ORDS MLE]An emailAddress been provided but it is NOT valid
2025-07-10T13:20:03.288Z INFO <4gTR34xEqj9T1zwHivW-og> [ORDS MLE]An emailAddress been provided and it is valid
You can see this for yourself, here are some sample calls using curl:
curl --json '{ "email": "abc" }' http://localhost:8080/ords/demouser/api/validate/
{"statusCode":400,"message":"abc is NOT a valid email address"}
curl --json '{ "email": "abc@def.com" }' http://localhost:8080/ords/demouser/api/validate/
{"statusCode":200,"message":"abc@def.com is a valid email address"}
curl --json '{ "foo": "abc" }' http://localhost:8080/ords/demouser/api/validate/
{"statusCode":422,"message":"you must provide a string representing an email address"}
Summary
ORDS 25.2 introduced a nice enhancement to ORDS logging, and with the proper setting should make it easier for you to perform some ad-hoc code troubleshooting.