A journey to find those pieces of software or technology that facilitate productive and maintainable software development

Showing posts with label Dojo. Show all posts
Showing posts with label Dojo. Show all posts

Thursday, June 28, 2007

Going Dijit-al: Migrating to Dojo 0.9 from 0.4

I have been using Dojo for some aspects of a commercial product to avoid the ugliness of JSF. However, some of the less desirable aspects of Dojo 0.4 have been recently addressed in a huge refactor being called Dojo 0.9. In order to take advantage of the big improvements - cardinal among these being consistent look & feel from the Dijit (Dojo Widget) package - I need to migrate our existing Dojo-dependent code over to Dojo 0.9. Apparently this is a fairly simple undertaking, but I have more ambitious goals than simply porting the code so it works. Dojo 0.9 has formalized and cleaned up the whole dojo.data package and data binding in general.

I would very much like for our Dojo Widgets to take advantage of this. Unfortunately, as of now, the Ajax fetching of data is mixed into these widgets directly. On top of that the Dojo 0.9 Beta refactor does not have the Grid dijit implemented so my heavy use of FilteringTable would require some temporary hacks to get working. It is still in for the Dojo 0.9 release later this month. Given my dislike of hacks I will port what I can around the FilteringTable's and leave them as placeholders for the time being. It looks like widgetsInTemplate is not working either so I will need to manually construct sub-widgets in my templates.

On the upside Dojo 0.9 introduces the dijit.Declaration widget which allows in-page refactoring of common components. It is an in-place widget declaration that can be immediately used within the same page for template-only widgets. Some of the Dojo Widgets I created could probably be done this way, but most of them rely heavily on maintaining instance-like state. It is however, an excellent launching point for refactoring existing repetitive HTML into something like a "function" instead of having to leap directly into making a full-blown widget to achieve the same effect.

So far the refactoring process has been painful, but mainly because of the terribly naive design decisions I made in my first round of Dojo-based development. A healthy dose of data bindings to separate the data management from the presentation should make the widgets easier to understand.

Monday, April 9, 2007

UI Event-handlers and Template-rendering belong on the Client

In my last post I briefly explored why JavaScript should be compelling to Java developers. It's time now to expand on that by showing how Dojo|The JavaScript Toolkit sheds light on how server-side handling of UI Event-handlers (aka Controllers), and Template Rendering is unnecessary, wasteful, and problematic. First, a clarification: I do not deny that server-side been a successful and important innovation. Server-side has been a wildly successful: it revolutionized web design, enabled the creation of web applications, and made the idea of dynamic content real. As part of this discussion I introduce ROCA: Resource-Oriented Composition Architecture.

Dynamic content is the concept, server-side is an implementation of this concept. What I will present is an alternative approach to Enterprise Web Application development which I call Resource-Oriented Composition Architecture or ROCA for short. The reason for this name is simple: it enables the composition of RESTful resources into what looks, feels, and acts as a unified application from the user's perspective while freeing the developers from the limitations of a single server or the complexities of SOA.

Why does ROCA push the controller to the client?

Why would you put UI Event-handling, and Template-rendering on the client? UI Event-handlers need to know what the user clicked and what the application's state is. They also need to be able to modify the presentation and state if the user's action necessitates it. Server-side event-handlers must have sufficient information passed to them to reconstruct this state and the resultant presentation and send it in a response to the client. Client-side event-handlers (aka Controllers) have the state and presentation immediately available to them and can act on and modify both flexibly and quickly in-place with requests to the server only when absolutely essential or desirable for things like periodic draft backup (which Blogger should have). Template-rendering is done to provide a presentation for the information on the server. Only the client needs this presentation, but many frameworks put this responsibility on the server.

How does ROCA push the controller to the client?

Dojo|The JavaScript Toolkit enables client-side rendering through it's Widgets facility. A Dojo Widget is a JavaScript module which points to CSS for styling and HTML for templating. It enables variable substitution and DHTML-style user interfaces. It also erases the problems of HTML and JavaScript snippet reuse that plagued earlier attempts at client-side templating through dojoAttachPoint attributes which acts like id attributes but are parsed into unique variables for each instance of a Widget allowing object-oriented DOM manipulation of the template.

Where is Application-state managed in ROCA?

How is state handled? The application exists purely in the user's browser. Sessions and action-tracking are done by the browser through cookies or other means that are available since this information is not needed by the server (some applications may want to store this information on the server for demographic/marketing purposes, but that is a separate concern). Application state is handled by managing JavaScript representations of resources retrieved from various RESTful JSON Servers and writing back changes in these resources to their respective servers.

Why is Application-state client-side in ROCA?

This is in direct contrast to most enterprise web application approaches which place these responsibilities on a single server which would act as a gateway to compose resources into a rigid presentation format on the server-side. Why does the application exist solely on the client? User's use applications, programs and user-agents do not. It is therefore unnecessary for an application as a whole to exist on a server. This is also done to avoid complicated application-layer client-server state synchronization. By keeping the server-side state at the transactional level the problem is reduced to ensuring persisted data-integrity (a task performed very well already by TCP, filesystems, and DBMSs). It also adheres to the DRY (Don't Repeat Yourself) principle by having a single home for application-layer state in the only place where it is needed: on the client.

What are the basic requirements of ROCA?

The primary server's role is to statically host the presentation code. Other servers (possibly including the primary server in certain cases) provide RESTful JSON interfaces to resources of interest: geographic location information, movie playtimes, blog posts, etc.

How could ROCA be implemented?

Dojo|The JavaScript Toolkit would be used to implement internationalization, accessibility, commons utility modules, controllers, and client-side templating. I would use lighttpd to statically host the Dojo code: modules, Widgets (and their templates), as well as the HTML index files that compose the Widgets into an application. J2EE servlets would be used to authenticate requesters and map POST, GET, PUT, and DELETE to Create, Retrieve, Update, and Destroy operations for a resource type. If many resources reside on a single server a single such servlet would act as a switch to forward requests for them to resource controllers.

Why ROCA instead of SOA?

SOA violates HTTP semantics:
  1. embeds request parameters in SOAP XML
  2. uses POST only regardless of semantic meaning or side-effects of request
  3. encourages credential embedding in SOAP XML
SOA is not as simple as it looks:
  1. client/server code is very complex and is usually generated by tools (lots of magic)
  2. no clear way to integrate with JavaScript
  3. client dev requires .NET/Java/etc.: difficult for non-enterprise web developers
SOA is not efficient:
  1. XML is less expressive than JSON: more bytes to convey the same information
  2. XML is more expensive to parse than JSON: more overhead on the client
  3. requests are XML: more overhead on the server
ROCA honours HTTP:
  1. sends request parameters as key=value pairs
  2. POST/GET/PUT/DELETE to create/retrieve/update/delete resources
  3. credentials conveyed in HTTP Authentication request header (free if the client is a browser)
ROCA is simpler to understand:
  1. client/server code is very simple and easy hand-code (no magic)
  2. trivially integrated with JavaScript
  3. requires HTML and JavaScript: common skills amongst web-designers
ROCA is efficient:
  1. presentation code is static and thus trivially cacheable
  2. JSON is more expressive than XML: less bytes to convey the same information
  3. JSON is less expensive to parse than XML: less overhead on client
  4. requests are standard HTTP key=value: less overhead on the server

Java Developer... Meet JavaScript

You've seen it around, it's been exhaulted as the saviour of web-based interaction, dragged through the mud as a security disaster suitable only for newbies and script-kiddies, and recently recast by some as the foundation of Web 2.0. It's none of the above, yet lends to all of them for good or ill.

Why am I posting this? I am posting it because I believe that the J2EE community has been unwilling to seriously adopt JavaScript as a foundational component of their development. With tools such as The Dojo Toolkit it is now possible for Java-centric developers such as myself to develop in JavaScript without our heads exploding with worry about global-scope collisions and undeclared dependencies. In fact, I'd wager that a Java developer who invests his Digg time instead on learning Dojo and by proxy JavaScript itself, will find Java less and less compelling as the power of closures, true Aspect-Oriented Programming, and literal object and regular expression syntax sinks in.

A simple example of JavaScript's powerful literal syntax: "CustNH".split(/(?=[A-Z])/) returns ["Cust","N","H"]. This is effectively a very concise CamelCase parser.

Imagine now that you are using this string to drive an Autocompleter such as the one from script.aculo.us. You can now do completion from CamelCase to search an API to give a result like CustomNavigationHandler (for those familiar with JavaServer Faces).

That's just a trivial example but it illustrates how concise JavaScript is. In my next post I will discuss why UI events are best handled by the client-side and explore the idea of using Dojo and a RESTful JSON Server to push the Controller and Template Rendering responsibilities to the client.

Conclusion: JavaScript is well worth the effort to learn.

See: A re-introduction to JavaScript on Mozilla's site for a cross-browser intro to JavaScript.

SyntaxHighlighter