Upload
marko-goricki
View
304
Download
5
Embed Size (px)
Citation preview
Speed Up Your APEX Apps with JSON and Handlebars
Marko GoričkiBiLog
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
About Me• started with Oracle Forms and Reports• working 8 years with APEX• APEX related blog - apexbyg.blogspot.com• @mgoricki
It dependsThere 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”
Content
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
JSON format• {“name”: value, “name”: value…}• key elements• Name• Value• Object (unordered collection)• Array (ordered collection)
Name/key/attribute
Value
Object
Array
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
Object• unordered set of name/value pairs• begins and ends with brace - {…}• name/string/attribute/key followed by colon• separated by comma
Array• ordered collection of values• begins and ends with brackets - […]• separated by comma
*Please, don’t use this in your CV !!
JSON vs XMLJSON 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
Generate JSON• prior to APEX 5:• by manually concatenating strings• apex_util.json_from_*• PL/JSON
Generate JSON•with APEX 5 - APEX_JSON API package
Generate JSON• Other solutions• Oracle REST Data Services (ORDS) • node.js
SQL source
• why short column alias (x, a, b and c)? • JSON size:
• 500 rows - 29.1KB vs 43.3KB
• less readable vs ≈30% smaller size
SQL sourceWith short aliasWithout alias
Generate JSON•Manually by concatenating strings• apex_util.json_from_*• PL/JSON library• APEX_JSON package• ORDS
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
Generate JSON•Manually by concatenating strings• apex_util.json_from_*• PL/JSON library• APEX_JSON package• ORDS
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
Generate JSON•Manually by concatenating strings• apex_util.json_from_*• PL/JSON library• APEX_JSON package• ORDS
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
Generate JSON•Manually by concatenating strings• apex_util.json_from_*• PL/JSON library• APEX_JSON package• ORDS
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+
APEX_JSON API• Simple JSON Arrayapex_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;
Nested JSON object - with cursordeclare 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;
Parsing simple JSON object
declare v_json_object varchar2(100) := '{"dname":"ACCOUNTING","loc":"NEW YORK"}';begin apex_json.parse(v_json_object); dbms_output.put_line( apex_json.get_varchar2('dname') );end;
Parsing nested JSON objectdeclare v_json_object clob := ‘{…}’;begin apex_json.parse(v_json_object); dbms_output.put_line( apex_json.get_varchar2('DEPTS[1].EMPS[2].ENAME') ); dbms_output.put_line( apex_json.get_varchar2(p_path => 'DEPTS[%d].EMPS[%d].ENAME’ , p0 => 1 , p1 => 2) ); end;
Generate JSON•Manually by concatenating strings• apex_util.json_from_*• PL/JSON library• APEX_JSON package• ORDS
Oracle REST Data Services (ORDS)• easy to develop modern REST interfaces• ways to use it:
• APEX GUI• SQL Developer (auto-rest)• PL/SQL API
• Simple Oracle Document Access (SODA) API over REST• URL format:
• protocol://host:port/ords-name/apex-workspace-name/uri-template/bind-value • https://apex.oracle.com/pls/apex/mgoricki/dept/10
ORDS Demo
Oracle Rest Data Services (ORDS)• CONS• little slower• you need ORDS
• PROS• declarative and simple• many options• easy to create nested JSON objects
Best method?• It depends!
ORDS
PL/JSON
apex_json
apex_util.json_from_sql
Manually
0.00 200.00 400.00 600.00 800.00 1000.00 1200.00 1400.00 1600.00 1800.00
657.80
1574.00
287.00
332.80
254.70
Average execution time (ms)
ORDS
PL/JSON
apex_json
apex_util.json_from_sql
Manually
29.00 29.10 29.20 29.30 29.40 29.50 29.60 29.70 29.80 29.90 30.00
29.90
29.30
29.30
29.30
29.30
Average JSON size (KB)
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
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"}');
JSON and Oracle12c• parsing JSON data
SQL> select json.json_col.dname from my_json json;
DNAME---------ACCOUNTING
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
Old HTML way
HTTP Request
HTML page
Client / Browser Server / DB
AJAX partial page
AJAX Request
HTML part
Client / Browser Server / DB
Client side templates
AJAX Request
JSON
HTML Template
Client / Browser Server / DB
• 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
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}}
In APEX• Add JS library
• Create template item
• Define HTML object where to put result
• Fetch JSON and run render function
In APEX
Example
Classic report example
Report region
ORDS
PL/JSON
apex_json
apex_util.json_from_sql
Manually
0.00 200.00 400.00 600.00 800.00 1000.00 1200.00 1400.00 1600.00 1800.00
578.80
657.80
1574.00
287.00
332.80
254.70
Average execution time (ms)
Report region
ORDS
PL/JSON
apex_json
apex_util.json_from_sql
Manually
0.00 20.00 40.00 60.00 80.00 100.00 120.00 140.00
122.00
29.90
29.30
29.30
29.30
29.30
Average JSON size (KB)
Real-life example
Generation time: 2 minutesResponse time: 2.3 MB
Only first 700 rows
Real-life example
Generation time: 2.9s vs 2 minutesResponse time: 500KB vs 2.3 MB
All 2422 rows vs 700 rows
Q&A