11 Extending ORDS Functionality with Plugins

This chapter explains and provides examples on using ORDS plugin framework.

ORDS has a plugin framework that allows you to add your own custom functionality into the ORDS web application. Plugins can be added to the ORDS runtime by placing the jar files in the lib/ext directory. The ORDS distribution contains the source for example plugins. The plugin examples can be built using Apache ant, a software tool used for automating the build processes.

11.1 Plugin Demonstration Example

This section shows how you can locate and build a plugin demonstration example..

The plugin-demonstraion example is at examples/plugins/plugin-demo location and contains the source for a HttpServlet that gets a database connection injected at runtime. The servlet uses that JDBC database connection to run a query in the database and return a response at runtime.

Perform the following steps to build and use the demonstration example:
  1. Change the directory to examples/plugins/plugin-demo
  2. Run ant to build the examples/plugins/plugin-demo/built/plugin-demo.jar file
  3. Copy the plugin-demo.jar to the ORDS distribution lib/ext directory and start an ORDS instance.
  4. Invoke the servlet using the following URL pattern: http://server/ords/schema/demos/plugin?who=somebody
    1. For example: http://localhost:8080/ords/hr/demos/plugin?who=scott where ORDS is configured with a default pool and HR is an alias for a REST Enabled Schema in that database.
The details of developing and deploying Java based plugins is available in the Oracle REST Data Services Java API Reference book.

11.2 Embedding Graal JavaScript Component

The JavaScript component must be embedded as a plugin to be able to run JavaScript as a guest language in ORDS that is running in GraalVM for JDK version 21.

The following are the artifacts required to embed JavaScript:
  • GraalVM Polyglot API
  • JavaScript language
The following is a sample code snippet that demonstrates Maven dependency setup that can help you get the required dependencies:
<dependency>
    <groupId>org.graalvm.polyglot</groupId>
    <artifactId>polyglot</artifactId>
    <version>${graalvm.version}</version>
</dependency>
<dependency>
    <groupId>org.graalvm.polyglot</groupId>
    <!-- Language: js -->
    <artifactId>js</artifactId>
    <version>${graalvm.version}</version>
    <type>pom</type>
</dependency>

Refer to section, Embedding Languages in the GraalVM reference manual for more information about dependency setup to embed languages. Once the required artifacts have be dowloaded, place them in lib/ext/ directory to be included in the classpath at runtime.

11.3 Plugin Javascript

ORDS provides a JavaScript as a service framework for customers to define a JavaScript that can be executed in the ORDS instance on request. This is similar to the conventional RESTful services concept used to develop the applications. The framework is based on the module, template, and handler architecture. See Developing Oracle REST Data Services Applications. Rather than defining the modules, templates, and handlers in the database, they are specified in an XML representation that is read from lib/ext/ directory as a plugin.

The ORDS examples directory contains a plugin-javascript example and the source can be found in the examples/plugins/plugin-javascript directory. This section describes the key elements of the plugin.

Note:

GraalVM with JS component is required for JavaScript plugin ORDS feature to work.
GraalVM with JS component is required for this ORDS feature to work. See GraalVM Configuration for more information.

The example contains a number of inline and external definitions for JavaScript source. References to external JavaScript source are to the files that are found in the classpath.

File Description
build.xml The ant build project.
src/js/example.js An example external JavaScript file. External here means, not defined in, but referred to from, the XML Resource Module file.
src/META-INF/manifest.json A plugin configuration metadata file that ORDS reads at startup to register XML Resource Modules.
src/META-ING/modules/javascript.xml An XML Resource Module file that defines an example module with a number of templates and handlers.
Perform the following steps to build and use the example:
  1. Change the directory to examples/plugins/plugin-javascript.
  2. Run ant to build examples/plugins/plugin-javascript/built/plugin-javascript.jar file.
  3. Copy the plugin-javascript.jar file to the ORDS distribution lib/ext directory and start the ORDS instance using a supported GraalVM with JS component.
  4. Invoke the defined handlers using the URL pattern: http://server/ords/javascript-examples/{template pattern}.
    1. For example: http://localhost:8080/ords/javascript-examples/now where the current time is returned.

      Note:

      Unlike the ORDS REST Services, the JavaScript as a service implementation does not require or use a database connection.

11.3.1 Example Services Purpose and Use

This section provides the information on the purpose and use of the example services.

Purpose Request Action Response
An example of inline Javascript that returns the current UTC time as application/json. /ords/javascript-examples/now GET { "now":"2023-08-31T16:08:55.471Z" }
An example of inline Javascript that accepts a parameter. /ords/javascript-examples/future?days=7 GET { "now":"2023-08-31T16:08:55.471Z", "future":"2023-09-07T16:08:55.471Z", "days":7 }
An example of inline Javascript that accepts various parameters from different sources.
/ords/javascript-examples/hello?name=Ted

curl --location 'ords/javascript-examples/hello' \
--header 'Agent: Test'
GET
Hello Ted
Hello Test
An example of external Javascript file that accepts a parameter. /ords/javascript-examples/fibonacci?length=50 GET {fib: 12586269025}
An example of inline Javascript that uses implicit parameters content_type and body_text for getting the request values as well as using ords_response to invoke setStatus and setContentType on HttpServletResponse.
curl --location '/ords/hr/javascript-examples/countwords' \
--header 'Content-Type: application/json' \
--data '{"text": "How many words are here?"}'
POST
{"text": "How many words are here?","count": 5}