The document discusses various methods for generating JSON from SQL queries in Oracle APEX applications. It compares manually concatenating strings, using the apex_util.json_from_* procedures, the PL/JSON library, the APEX_JSON API package, and Oracle REST Data Services (ORDS). The APEX_JSON package is recommended for most cases as it supports generation and parsing, can be used standalone, has a light footprint, and makes conversion from XML easy. Using a templating engine like Handlebars.js with JSON is also presented as a way to dynamically render HTML from database queries.
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Speed Up Your APEX Apps with JSON and Handlebars
1.
2. Speed Up Your APEX Apps with JSON
and Handlebars
Marko Gorički
BiLog
3. About BiLog
• small IT company focused on consulting and business solution development
(using Oracle technologies)
• big APEX company ≈ 25 APEX developers
• our APEX products:
HRMb - HR management software
www.bilog.hr
4. About Me
• started with Oracle Forms and Reports
• working 8 years with APEX
• APEX related blog - apexbyg.blogspot.com
• @mgoricki
5. It depends
There are only five questions about the database:
• The answer to the first three questions is “use bind variables.”
• The answer to the fourth question is “do not use bind variables.”
• The answer to the fifth question is “it depends”.
If you know those answers, you can answer any question about the database!
– Tom Kyte
• In APEX: “it depends”
8. JSON
• JavaScript Object Notation – lightweight data interchange format that consists
of name-value pairs
• key features:
• easy to read and write
• easy to generate and parse
• language independent
• subset of JavaScript notation
9. JSON format
• {“name”: value, “name”: value…}
• key elements
• Name
• Value
• Object (unordered collection)
• Array (ordered collection)
Name/key/attribute
Value
Object
Array
10. Value
• string - double quotes(“”), backslash escapes ()
• number - decimal notation (possibly signed and possibly including a decimal
exponent)
• no date data type
• null different to SQL null
11. Object
• unordered set of name/value pairs
• begins and ends with brace - {…}
• name/string/attribute/key followed by colon
• separated by comma
14. JSON vs XML
JSON XML
Predefined data types
Typless or based on XML Schema or document type
definition (DTD)
Structured data Structured and semi-structured data
Data-centric Data or document-centric
Data representation language Document markup and data representation language
15.
16. Generate JSON
• prior to APEX 5:
• by manually concatenating strings
• apex_util.json_from_*
• PL/JSON
22. Manually by concatenating
strings
• using sys.htp package
• CONS:
• hard to maintain and develop
• manually escape values
• manually define value types
• easy to make mistakes
• no parsing
• PROS
• customizable
• it can be fast
24. Using apex_util.json_from*
• procedures: *_sql, *_array, *_items, *_string
• CONS:
• “not documented”
• no null, true and false values
• hard to create nested JSON objects
• no parsing
• security issue: passing string into json_from_sql
• PROS:
• simple and easy to develop
• auto escaping
• recognizes some value types (number)
• available before APEX 5
26. PL/JSON
• open source library (2009.)
• DB types: JSON (object) and JSON_LIST (array)
• CONS
• complex
• lack of real documentation
• performance issues
• PROS
• can be stored in DB
• parsing
• supports all value types
• open source
• available before APEX 5
28. APEX_JSON API
• PROS:
• native
• generating and parsing
• can be used as standalone (CLOB)
• light footprint
• easy conversion from/to xmltype
• CONS:
• only in APEX 5.0+
29. APEX_JSON API
• Simple JSON Array
apex_json.open_array;
for emp in (select *
from emp
where deptno = p_deptno)
loop
apex_json.write(emp.ename);
end loop;
apex_json.close_array;
30. Nested JSON object - with cursor
declare
cur_dept sys_refcursor;
begin
open cur_dept for
select d.dname
, d.loc
, cursor (select e.ename
, e.job
, e.sal
, (select m.ename from emp m where m.empno = e.mgr) manager
, decode(e.comm, null, 'false', 'true') as hasCommision
from emp e
where d.deptno = e.deptno) as emps
from dept d
where d.deptno = nvl(p_deptno, d.deptno);
apex_json.open_object;
apex_json.write('DEPTS',cur_dept);
apex_json.close_object;
end;
37. Oracle Rest Data Services (ORDS)
• CONS
• little slower
• you need ORDS
• PROS
• declarative and simple
• many options
• easy to create nested JSON objects
42. JSON and Oracle12c
• native support from 12.1.0.2
• store JSON data (with VARCHAR2, CLOB or BLOB data types), index,
query…
• parse JSON data with SQL
43. JSON and Oracle12c
• storing JSON data
create table my_json(
json_col clob
);
alter table my_json add constraint valid_json
check (json_col is json);
insert into my_json
values ('{"dname":"ACCOUNTING","loc":"NEW YORK"}');
44. JSON and Oracle12c
• parsing JSON data
SQL> select json.json_col.dname from my_json json;
DNAME
---------
ACCOUNTING
45. Using JSON
• APEX use it (IR, Page designer)
• New APEX 5.1 grid
• Oracle JET
• fetch asynchronously data with AJAX
• communicate with Web services (REST API - Twitter, Flickr, Google
Apps)
• easy to use with JavaScript
50. • light weighted JavaScript templating engine (Mustache.js,
AngularJS, Backbone.js, Ember.js, Marko.js…) used for client-side
data binding
• subset of Mustache.js + minimal logic
• works by expanding tags in a template using values provided by
JSON object
• tags can be replaced with value, nothing or series of values
Handlebars.js
52. Handlebars.js templates
• tags start and end with double braces (mustaches) {{…}}
• two simple types of tags:
• variables - basic tag type
{{title}}
• sections/block expressions - render block of text one or more times
{{#posts}}…{{/posts}}
Today I'll speek about how can you improve you apps by using JSON and templating engine called Handlebars.
- specialized in converting old and rusty Oracle Forms to new shiny APEX applications with responsive web design -
especially in insurance and banking
Some in house apps
we’ve had first APEX community qoute
BiLog Web Page is build in APEX
- maybe I don't look like this, but I've started working with Oracle Forms and Reports
- And I'm thankfull for this because it was a strong background for APEX
- last 8 years working with APEX and related web technologies
- I like to answer APEX questions and solve complicated problems so I write APEX related blog and tweets
When I talk about APEX I like to mention this quote from Tom Kyte about 3 answers that you have to know to answer any question about Oracle database.
In APEX its always it depends.
Everything can be solved in so many different ways and you’ll see that this is the case when we talk about JSON
Today I’ll speak about tree things:
Basic information about JSON
How to generate and parse JSON with PL/SQL
And at the end I’ll show interesting example how to use it together with Handlebars.js to IMPROVE your APEX applications
basic information about JSON
show you the ways how to generate JSON in Oracle and APEX
and at the end I’ll show interesting example how can you use it in you APEX app and IMPROVE functionalities
In some languages name-value is called attribute-value / key - value / string – value
easy to read and write – for humans
easy to generate and parse – for machines
Language independent – it’s text format that uses conventions that are familiar to programmers of many programming languages like C, C#, C++, Java, JavaScript, Perl, Python…; A variety of programming languages can parse and generate JSON data.
And that makes JSON ideal for data interchange
Subset of JavaScript notation – you can natively use it in JavaScript which is ideal for Web Apps, JSON can often be used in JavaScript programs without any need for parsing or serializing
• APEX interactive grid uses JSON
• Oracle JET report uses JSON
: colon, comma
What about JSON format? On the right side you can see sample JSON object that consists of employees from one department.
As I said, JSON is data interchange format that consists of name-value pairs.
On the left side you can see name part. Name should always be in double quotes (although Oracle DB 12s supports it without qoutes, APEX_JSON package doesn’t).
If you compare it to PL SQL:
Object - associative array
Array - varray
Name should always be in double quotes (although Oracle DB supports it without qoutes, but APEX_JSON doesn’t)
Can be 7 different data types.
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array
you have to be careful about null data type.
it’s not the same as SQL null value
if you query JSON object IS NULL to null column will return FALSE
SQL condition IS NULL condition returns false for a JSON null value, and SQL condition IS NOT NULL returns true.
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- similar to Oracle associative arrays
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
similar to PL SQL varray
and thats all you have to know about JSON
JSON is sticked to predefine datatypes in XML you can define custom ones by using XML Schema, DTD. It can be advantage but on the other side it becomes more complex and difficult to read
JSON is structured (in arrays and objects) and that makes JSON easy to handle in many programming languages. In other hand, XML is structured in trees
You can send files with XML, but not with JSON-on, its data centric and used only for sending data
With JSON you are sending only data, but with XML you are sending also the metadata that describes data that you are sending
In a case of Oracle DB, both JSON and XML can be used similar - stored, queried, indexed but it’s a bit different in UI (JavaScript)
I can say that JSON is best tool for sending data in AJAX communication
It’s like you have to dig a hole and only thing that you have it’s shovel
lopata = shovel
bager - dredge
higher level solutions that you’ll use when creating some API for others
Oracle REST Data Services (ORDS) - (mid tier Java application) makes it easy to develop modern REST interfaces for relational data in the Oracle Database and now
node.js - Node.js is an open-source, cross-platform runtime environment for developing server-side Web applications.
driver for Oracle DB
When it comes to generating JSON, Node.js seems like a natural choice as JSON is based on JavaScript objects.
However, it’s not exactly fair to compare a solution crafted in Node.js to the PL/SQL solutions as Node.js has a clear disadvantage: it runs on a separate server. That means we have to bring the data across the network before we can transform it to the desired output.
In this examples I’ve used this query for generating JSON
If you are using JSON internally, and in most cases in APEX you will, use short aliases.
You can document the code where you generate it
When you will use this – it depends – if you are creating pubic API
Name string is repeating and it takes unnecessary space
manually deal with escaping values
It can be fast – no additional engine logic
In case of JSON_FROM_SQL it can be dangerous:
can’t pass parameters or add bind variables - vulnerable to SQL injection
you can have problems with invalid SQL Query (if you remove column, drop table…)
- in most cases I’ve used this apex_util.json_from_array because its safer
Originally started in 2009
bigger foot print – 9 packages, and 4 object types
It uses some of object-oriented features of Oracle DB
PL/JSON can take some time to learn and get used to
Not documented – learn by looking at the examples
- comes with APEX 5, but it can be used as standalone (INITIALIZE_CLOB_OUTPUT procedure)
- parsing and generating utilities
- build and supported by Oracle
-JSON content to a HTP buffer
- it’s possible to redirect the output to a CLOB buffer instead
apex_json.open_array;
for emp in (select *
from emp
where deptno = p_deptno)
loop
apex_json.write(emp.ename);
end loop;
apex_json.close_array;
2 ways to do it:
1) manually writing logic
2) using sys_Refcursor
APEX_JSON.PARSE - two signature procedures:
1) parses a JSON-formatted varchar2 or clob to package global variable g_values
2) has different parameters, and outputs JSON into output variable
GET functions
GET_VALUE
GET_VARCHAR2
GET_NUMBER
GET_DATE
- dot notation
- more than one signature
- released in 2010 as APEX Listener
- REST support for JSON was added in 2011
The ORDS PL/SQL package contains subprograms (procedures and functions) for developing RESTful services using Oracle REST Data Services.
with ORDS 3.0 ships with the Oracle Database 12c Document Store JSON documents can now be stored in and retrieved from document collections managed by Oracle Database. SODA for REST provides an interface to the Oracle Database Document Store for NoSQL style application development.
APEX_JSON adds unnecessary blank spaces – only in debug mode
- stored, indexed, and queried
- Oracle Database queries are declarative
Functions json_value, json_query, and json_table.
Conditions json_exists, is json, is not json, and json_textcontains.
A dot notation that acts similar to a combination of json_value and json_query and resembles a SQL object access expression, that is, attribute dot notation for an abstract data type (ADT).
Oracle recommends that you always use an is_json check constraint to ensure that column values are valid JSON instances
Minimal Templating on Steroids
To better understand templating engines, lets look how HTML data can be fetched
I’ve googled about it
Minimal Templating on Steroids
Handlebars helpers, expressions, share templates, precompile templates
You can write JavaScript in helpers
HTML values are auto escaped
double braces {{ }}
half the time faster
size of JSON is 4 times smaller
Real life example - calendar with monthly working hours log