Call PL/SQL APIs Declaratively from APEX Using the Invoke API Process

Search for a command to run...

I think the list of reasons why can be extended in the context of an APEX environment. a) Compiling code in packages improves performance by lessening the amount of interpreted code that needs to be parsed at runtime. This can be significant, and is the reason it's encouraged to move plugin PL/SQL to a package instead of retaining the inline PL/SQL b) Any missing privileges you may have in your deployment are more likely to be found at compile time, not runtime. c) Testing - not mentioned in the linked post, but a suitably de-coupled procedure can be unit tested outside the scope of APEX.
Oracle APEX ideas and insights that you can read in four minutes or less.
Introduction I was working on a task recently where I needed to maintain an array of record IDs during a PL/SQL loop. I needed the array so I could mark successfully processed records after the loop was complete. This is pretty easy to do with PL/SQL...
Introduction One of the marquee features of APEX 26.1 was AI Interactive Reports. When I started testing this new feature, I was interested to see what was going on behind the scenes. In this post, I

Introduction One of the marquee features of APEX 26.1 is APEX AI Agents. APEX AI Agents allow you to use an LLM and your own PL/SQL and JS tools to perform actions on your data instead of just chattin

Introduction In my previous post, I looked at logging APEX AI Agent requests and responses with Request and Response handlers. Logging is the first step because it shows you what is actually moving th

Introduction Logging is one of the first things you need when building serious AI Agents. Without it, debugging quickly becomes guesswork. You can see the final answer, but not always why the model ch

Context management patterns from building agents in Oracle APEX

Until APEX 22.2, the primary method for calling code in a PL/SQL package from an APEX page process was to use the Execute Code page process type. In this post, I will describe the Invoke API process type, which allows you to call PL/SQL procedures and functions declaratively.
Throughout this post, I will use an example of a simple APEX form that allows you to create employee records. After creating an employee, I need to call a PL/SQL procedure to onboard the employee (provision a laptop, send a welcome email, etc.).

The onboarding process is initiated by calling the procedure onboard_employee in the package cn_blog_demo_pk.
PROCEDURE onboard_employee
(employee_id IN NUMBER,
laptop_type IN VARCHAR2) IS
BEGIN
apex_debug.info('employee_id [%s], laptop_type[%s]', employee_id, laptop_type);
-- Do Stuff here to perform onboarding.
END onboard_employee;
Before the Invoke API process type came along, we would have created an Execute Code process type, something like this:

Perhaps the best way to illustrate the new approach is via a short video. The video below shows me creating a new Invoke API page process to call the onboard_employee procedure declaratively.
As you can see, the process of selecting the PL/SQL procedure and passing parameters from the APEX page to the procedure was completely declarative.
💡Although you can select a Type of PL/SQL Procedure or Function in the Process Settings, please don't. I advise you to keep all PL/SQL procedures and functions in a package. This post lists some of the reasons why.
There are several options for populating the parameters of the underlying PL/SQL API; these are:
Static Value - Set the parameter to a Static Value.
Item - Set the parameter to the value held in the session state for an APEX Item.
SQL Query (return single value) - Set the parameter to the first value returned from a SQL Query.
Expression - Set the parameter to the result of an Expression.
Function Body - Set the parameter to the value returned from a Function Body.
Preference - Set the parameter to the value of an APEX Preference.
API Default - Use the value defined as default in the API parameter declaration.
Null - Set the parameter to NULL.
💡APEX will automatically set the API parameters to page items from the current page if their names match.
The Invoke API process type handles boolean types quite nicely. If I were to add a boolean parameter to my underlying procedure as follows:
PROCEDURE onboard_employee
(employee_id IN NUMBER,
laptop_type IN VARCHAR2,
international IN BOOLEAN);
When I re-sync the parameters in APEX, I can map a true false value from the page item (which is a Switch-type page item in this case) to indicate what value represents true and what value represents false. In this case, if the item P10_INTERNATIONAL_EMP has a value of Y, the Invoke API Process will pass TRUE to the underlying procedure.

If you have OUT (or IN OUT) parameters in the underlying PL/SQL API, these values will be passed to the mapped page item when the API completes. For example, if I add the x_message as an OUT parameter as follows:
PROCEDURE onboard_employee
(employee_id IN NUMBER,
laptop_type IN VARCHAR2,
international IN BOOLEAN,
x_message OUT VARCHAR2);
After re-syncing the parameters, I can map the value of the message OUT parameter to a page item.

💡If you don't need to do anything with an out parameter, you can just flip the Ignore Output switch, and APEX will generate a dummy variable to receive the out value, and you won't have to assign it to anything.
As you would expect, an Invoke API page process will break if you change the underlying PL/SQL procedure or function.


💡Hopefully, you are using the APEX Error Handling Function, so your users do not see these kinds of ugly and potentially security risky error messages.
If the name of the underlying package, procedure, or function changes, you must re-select it in the region settings and re-set up the parameters.
If you change the underlying PL/SQL API parameters, you can re-sync the parameters in the Invoke API process by right-clicking on the Parameters section and clicking Synchronize Parameters.

You may wonder why you should bother with Invoke API processes. As you can see from the examples above, we did not have to write much code to call a PL/SQL API before the Invoke API process came along.
While Invoke API process types do not introduce groundbreaking functionality, they make things easier for citizen developers and encourage best practices for experienced developers.
Citizen Developers can now declaratively select a procedure and populate its parameters. Having said that, someone (presumably an experienced developer) has to create the PL/SQL package and logic.
Experienced Developers are forced to put all their code in a PL/SQL package. I don't know about you, but when I need to change an Execute Code type process quickly, I am tempted to add the code to the PL/SQL block in the page process instead of opening the package and adding the code there. Invoke API processes will end that practice, and I am glad.
In this post, I introduced you to the Invoke API page process. I do not think the Invoke API process is a game changer, but it supports best practices by forcing you to keep your code in PL/SQL packages.
I wrote this post before APEX 23.1 was announced. The post is still relevant but misses out on a new feature where you can now Invoke REST Sources. It works the same way as invoking PL/SQL APIs, i.e., you select a REST Source from a list of values, and the REST Source Parameters are displayed so you can easily pass in parameters.
- 🩳 APEX Shorts
- 📝 APEX Posts