Architecture for Modern Web Applications
Before doing a deep dive into implementation details, let's look at web architectures and patterns in order to classify Oracle JET properly and get a better understanding. The de facto standard pattern is MVC (Model-View-Controller) on the server side. Whether you are using Perl, PHP, Phyton or the Oracle/Java-based techniques like JSPs (Java Server Pages), Struts (Open Source Apache Framework), JSF (Java Server Faces) or ADF Faces, best practice is to separate your code into Model, View and Controller. See Figure 1 for illustration of this traditional pattern.
Figure 1: Server-Side Web Architecture using Model-View-Controller pattern
Figure 2: Client-side web architecture for SPAs using MVVM pattern
The Model represents the application data, while the ViewModel exposes data from the Model to the View and maintains the application's (UI) state. The View defines the representation of how it should be displayed visually. To improve user experience (UX), modern web applications use the local storage HTML5 feature implemented by all modern browsers.
These kinds of applications typically communicate with the backend system through JSON-based RESTful APIs. Recent evolutions recommend a dedicated "Backend For Frontend"-API (BFF-API) on the server-side which exposes application optimized APIs rather than generic enterprise APIs. The BFF-API is based on custom business logic or simply uses existing enterprise APIs or third-party Cloud APIs (e.g., Google Maps, etc).
By the way: Mobile Cloud Service (MCS) is built with exactly the same architectural principles in mind. It enables you to create app-specific Mobile Backend as a Service (MBaaS) that can be composed of existing general purpose APIs.
Alta UI is the default
From my perspective, Oracle's Alta UI initiative is a logical move. Not only does it simplify the UI and improve the overall UX, it also enables existing enterprise applications to be modernized as lean architectures using Microservices and integration through RESTful services. Unsurprisingly, the default theme for Oracle JET UI components is Alta UI.
Oracle JET Development: The Basics
jQuery UI is a set of UI widgets, interaction effects, and themes built on top of the jQuery library. Oracle JET uses these concepts to expose all JET UI components as theme-able UI widgets.
Listing 1: Basic example of Knockout's binding and computation feature
Listing 3: js/main.js: RequireJS loads required dependencies, then notifies via callback
SASS (Syntactically Awesome Style Sheets) extends CSS3 and enables you to use variables, nested rules, mixins, and inline imports. Oracle JET uses the SCSS (Sassy CSS) syntax of SASS. Unless you want to create your own theme or override parts of the Alta theme, you do not really need to know many details about SASS. But it certainly will help you become an Oracle JET ninja.
Oracle JET components use Hammer.js internally for gesture support. You do not need to know more about it to get started with JET development.
Rich UI Components Set
One of the most impressive things about Oracle JET is that it comes with a rich set of user interface components, including all traditional input elements for building beautiful UIs in great looking layouts, as well as comprehensive data visualization components. See Figure 3, below, to get a glimpse of some of the more complex UI components Oracle JET gives you.
Figure 3: Modern user interaction components available out-of-the box
Beyond the UI component set, style classes are available for implementing a powerful 12-column responsive grid system that supports four different device sizes: small, medium, large, x-large. See the Oracle JET Development Guide for great examples.
Built with Accessibility in Mind
Accessibility does not get as much attention as it should. Accessibility means that someone working with assistive technology (like a screen reader) can explore and use the web application without a touch or mouse input device, using only keyboard and braille display. For the visually impaired, it is very important to have such color contrasts that the application is usable on black/white screens.
Creating accessible web applications is a great challenge. Having a toolkit in which these requirements are implemented from the beginning is just awesome. Figure 4 shows an example of how Oracle JET implements the Input Date UI Component through proper usage of WAI-ARIA attributes:
Figure 4: WAI-ARIA attributes make Oracle JET's InputDate (with DatePicker) UI component accessible by default
In the given example, the aria-describedby attribute is used in conjunction with a visually hidden div-element to give screen readers additional information on the input component. It is the resulting HTML5 code. There's no need to care about that when developing the UI with Oracle JET--the ojInputDate component handles all that.
Internationalization (i18n) and Localization (l10n)
Oracle JET has great support for i18n and l10n. For right-to-left languages (such as Arabic and Hebrew), there is built-in support in existing JET components (see example ojInputDateTime in Figure 5, below):
Figure 5: Internationalization with right-to-left language support
The default theme in Oracle JET is Alta UI, implemented by utilizing SASS features. The only single 3rd-party CSS included is normalize.css. It is recommended that you extend the default Alta theme by overriding the desired parts or extending your own custom components. This makes total sense since the Oracle UX team has invested a lot of effort.
According to the Oracle JET development guide (v1.1.2), support for custom themes is also available.
The most important part should be secured on your server-side. On the client side, you have to deal with some security aspects as well. Oracle JET does so by following common best practices inside its rich UI components. That is:
- Not using inline script elements
- Not generating random numbers
- Escaping/sanitizing all generated HTML code
Oracle JET also brings an oj.OAuth API, which supports the OAuth 2.0 protocol, but I am not going into details about that in this article.
Working with the Oracle JET Cookbook
Set Up a New Oracle JET Application
Figure 7: Modular Oracle JET Quickstart Template
Listing 5: index.html: Modular SPA template
With the ojModule directive you are telling Oracle JET to bind the given div element to the navContent.tmpl.html (the suffix is predefined in main.js). This is how it works for the Navigation and Complementary regions. For the dynamic Main Content region, it derives the name (of the JS file that contains the ViewModel and the HTML template filename) from the router. The return value of router.stateId() is set to the current value of the ojRouter object. The ojRouter object is defined with an initial value of "home" in the application's main.js file, which bootstraps the application. See Listing 6:
Listing 6: js/main.js: The ojRouter enables dynamic regions in Oracle JET
Since "home" is defined as default in the router configuration, Oracle JET will initially render home.tmpl.html template with the home.js view model.
Note: You will see „var self = this; self.firstName = etc…“ in nearly every view model. Since "this" refers to different objects depending on the call-stack / execution context, one can save a reference to a particular object by assigning it to another variable (here: "self“).
To summarize: the QuickStart template follows the Alta UI design principles and best practices and is a good starting point for new applications--just remove unneeded parts and you are good to go.
Going to Real World Requirements: Display Data from RESTful Services
To go beyond introductory basics, it is good to see a more sophisticated example. As described, it is common to consume data from RESTful services. Figure 8 demonstrates the result of the following basic example displaying a table of employees:
Figure 8: Displaying JSON data in a basic sortable table
As a newbie to Oracle JET, you need the following to create this by your own: JET Development Guide and JET Cookbook for the basic table, and of course a JSON source (e.g., https://gist.github.com/multikoop/98a664f3c39782a60913).
Starting with the HTML view, the template is pretty straightforward. Copy the code snippet and paste in home.tmpl.html (see Listing 7):
Listing 7: home.tmpl.html: HTML/Knockout template for a basic sortable table
Next, the bound datasource must be defined in the ViewModel. Actually, the datasource object is responsible for serving the Collection and fetching the JSON data. See Listing 8, below, for the empViewModel, defined in modules/home.js to get the idea.
Listing 8: modules/home.js: The View Model for the employees basic table
The most interesting parts here are the concept of the Model and the Collection: Emp-Model defines a single record, while Collection represents a list of those records. Oracle JET brings some basics like the oj.Model, oj.Collection, and oj.CollectionTableDataSource, which triggers the underlying operations (fetch, parse, etc.) for you.
Optionally, if you need to customize the mapping between JSON attributes and your View Model, you can define a "Parse“ function. To keep the sample simple, it is commented.
Deploying and Running JET Applications
Tools and Best Practices
NetBeans with Oracle JET Plugin
Download NetBeans (minimum version 8.1), install and start it. Next, install the JET Plugin through Tools > Plugins > Search for JET and get going.
Fig. 9: Oracle JET Support Plugin for NetBeans
Once the Oracle JET Plugin is installed, select New Project and search for "jet“ to strip down the choice (See Figure 10):
Fig. 10: Create a new project based on the Oracle JET QuickStart Template right from NetBeans
Figure 11: The NetBeans Connector greatly improves productivity while developing and debugging Oracle JET applications
Summary and a Look into the Future
- Oracle JET Homepage
- Download Netbeans 8.1 or higher
- Download Oracle JET Quickstart Template
- View Oracle JET Cookbook
- View Oracle JET Development Guide
- Check out the Oracle JET Community Space
Stay informed of Oracle JET product updates and community driven content by following:
- Knockout: learn.knockoutjs.com
- RequireJS: http://requirejs.org/
- jQuery / jQueryUI: https://jquery.com/
- SASS: http://sass-lang.com/
About the Author
Oracle ACE Director Andreas Koop (@andreaskoop) is working as Solution Architect, Technical Lead or Trainer on different IT projects using Oracle technology. He is co-founder of enpit, a German-based company specializing in Consulting Services for Oracle Middleware technologies and Oracle Cloud offerings. He enables customers to successfully implement Business Solutions based on Oracle Middleware & Oracle Cloud products. As an active member of the German Oracle User Group (DOAG) and regular speaker at different conferences, Andreas shares his knowledge with the worldwide Oracle Community on his blog, in community meetings, on GitHub or on social media channels. In his spare time he enjoys life with his wife, family and friends. Whenever time permits, Andreas is making music, playing soccer, and biking.
This article represents the expertise, findings, and opinion of the author. It has been published by Oracle in this space as part of a larger effort to encourage the exchange of such information within this Community, and to promote evaluation and commentary by peers. This article has not been reviewed by the relevant Oracle product team for compliance with Oracle's standards and practices, and its publication should not be interpreted as an endorsement by Oracle of the statements expressed therein.