JSF and MVVM ?

A view days ago my  colleague Sönke Sothman gave an excellent talk about knockout.js and the MVVM pattern at one of our internal know-how meetings. His presentation showed a lot of nice usage scenarios where user experience was enhanced by pure client side operations without the need of any callbacks to the server. I was thinking about potential usage scenarios of MVVM in JSF applications and if we could benefit from  it.

Beeing a JSF developer, I am used to work with server side models requiring client side components to communicate with the server side pretty often. So it crossed my mind more than once that a lot of those roundtrips should be avoided. Think of a simple data table with dynamic number of rows. You could edit existing rows, add new ones or remove some of them. Where is the point of  having server side listeners to interact on client side actions? Well,  if there are input components you certainly want to have them validated, but this could be done later on, all at once upon form submission. Wouldnt it be nice to manipulate data on the client side and send a single call to the server once you are done? This is where MVVM comes to play.

An example to get started…

Table components in JSF are usually bound to a DataModel or Collection of objects. This binding is existent on the server side. Once the component gets rendered, the Collection or DataModel will be processed and HTML markup is beeing generated by the components renderers in the last phase of the JSF lifecycle. After rendering phase, this markup is static (there is no further datastructure on the client side describing how to build the HTML table, besides the DOM). If we want to manipulate the number of rows we would typically stick to asynchronous calls to the server to change the model (a JSF managed bean or an attribute of a JSF managed bean) and rerender the table on the client side once we are finished  with dealing with the model. Rendering in this case means that JSF has to generate some HTML snippet, representing the current state of the data table based on the updated model, and  send this snippet to the client. JSF provides some JavaScript to automatically update the browser window with the recieved snippet.

While it is easy to follow this common approach it requires server callbacks with every action that needs to manipulate the model our table component is bound to.

Now let’s think of this scanrio using an MVVM approach:
In this case there would be a client side representation of our server-side model, the ViewModel. While this might be a one-to-one representation of our server side model, it is more desireable to have the ViewModel limited to those parts that you really need on the client side. This could be some component state (e.g. the column that was used for sorting the tables content) and of course the data to be displayed within the table. Given that the table is bound to the ViewModel on the client side, we could now add, edit or remove rows by manipulating the VieModel on the client side and update the table without any server callbacks. The ViewModel will be merged with the server-side model when you finally hit that “submit” button at the very end of your editing session.

Sounds good, so where is the catch?

Well, while some JSF libraries allow for client side manipulation without getting in touch with JavaScript, there is no such thing as a common concept for a client side model besides DOM. If you want to manipulate stuff on the client side, go ahead, write some JavaScript an see for yourself if it works with the JSF components of your choice ;-) . The Client Behavior API might be helpfull, but in most cases you might have to adopt the components or renderers code. Or, of course, just create a composite component from scratch with the desired client behaviour (JSF’s concept of composite components is one of my favorite JSF 2 features). All in all a maneagable task, but it tends to get code intensive soon.

While this simple example demonstrates pretty well why a client side model would be nice to have, there are other, maybe more sophisticated, usage scenarios. Think about HTML5’s web storage: Whenever needed, the ViewModel could be persisted in the browsers own storage and loaded whenever needed. Pretty nice feature if your web application is supposed to be used by mobile devices with unreliable connection to the server. Whenever there is no reception on your smartphone, just hit that “save my work” button you just added to your form to save the ViewState to the browsers web storage and proceed whenever the bars are back in the upper left corner of your iPhone ;-)

Ok, so what do we need?

Some JSF libraries provide concepts for client side manipulation. PrimeFaces for example enables you to assign “widgetVars” to some components. These are client-side identifiers that can be used declaratively in your view definition to  execute some actions on the client side. Again, this can be done without a single line of JavaScript but you are free to use those identifiers in scripts if you wish to do so. While this is a nice approach it is far away from the concept of a ViewModel. And it’s proprietary, of course. So your client side scripts will work well with Primefaces an only Primefaces.

Lets take a closer look the MVVM pattern to see whats on our todo list:

The first M in MVVM stands for Model, and it is the very same model that we use in our MVC approach. In fact MVVM does not replace MVC, I rather prefer to see it as an additon to MVC, so there is nothing new here.

The first V in MVVM stands for View and again, there is nothing new to this part. It is the component that takes care of the client side representation. So there wont be any notable change to our views since we will continue to define them using Facelets.

VM in MVVM stands for the ViewModel, our client side model. The ViewModel is bound to the Model but it is exisitent only on the client side, though you are free to sync it whenever needed with the Model on the server side. But, more important is, that you can do whatever you want on the client side without having to send callbacks to the server.

First of all we need a next-generation-JSF-implementation, which supports the MVVM concept.  The ViewModel would be created by this yet to come JSF implementation before a requested view is delivered to the client. Our ViewModel will be created from one or more JSF Managed Beans that form the Model. I can think of a nice set of class- and field-level annotations to tell JSF what parts of our model should make up the ViewModel on the client side. Once the view is delivered to the client, the ViewModel will be manipulated by client side scripts upon the form is submitted. Then, in the following iteration of the request processing lifecycle,  JSF has to deal with resynchronization between ViewModel and Model. Admittedly, this might be the most tricky part, but I’m confident that the Next-Gen JSF Impl will manage to do that ;-)

In the case of our table example, resynchronization means to deal with all the new rows of our table, the removed ones and of course the input fields that magically appeared on the client side, but dont have a representation in the component tree on the server side yet. Well, at least until now: New components will be created within the context of a special container component (a feature of our next gen JSF impl) that takes care to create the missing nodes in the server-side component tree. Validation, model update and invocation of application specific code would happen as usual from now on, but the semantics of the Render Response phase of the JSF lifecycle would slightly change: Instead of rendering the whole HTML of our data table, only the ViewModel and approriate calls to client side JavaScript functions would be created and sent to the client. Once recieved, client side scripts would create the table from the ViewModel. Rendering would be shiftet mostly to the client side, leaving the renderers almost only with task to write the ViewModel somewhere in the generated output stream while jQuery and friends create the table from the ViewModel on the client side.

Sounds like more Javascript is coming …

Yep. At least in the first place. JavaScript is feared for some reasons by a lot of developers but the truth is JavaScript is out there and it won’t go away. It recently successfully made the jump to the server side (think about Node.js) and with HTML5 there will be more and more of it on the client side. A number of shiny, new API’s is waiting in HTML5-ready Browsers for us developers and they are all going to be used with JavaScript. So why are we (or at least some of us) so anxious about it? It is because of all the suffering developers had to bear since JavaScript made its debut more than 15 years ago: Poor tooling, bad browser support,lacking of knowledge and so on. The good news is that things are getting better. JavaScript support in IDE’s is improving, inconsistencys between browsers become more infrequent. So, if you avoided to get in touch with JavaScript until today, now is the time to make yourself familiar with it.

But we dont need to rely on JavaScript only to improve user experience. Using JSF means to work with UI components on a rather high level of abstraction. Beeing able to improve things on the client side with JavaScript is nice, but there should also be a way to do so declaratively. The (meanwhile stongly demanded) next-gen-JSF-implementation will provide a set of functional components to trigger client-side actions like persisting the ViewModel to the browsers web storage. Those components will abstract from the client side JavaScript API’s and enable developers to wire them up with command components (buttons, links, etc). Things like

<br />
<h:commandButton value="Save"><br />
   <h:webStorage persist="#{viewModel}" /><br />
</h:commandButton><br />

offer a convenient way to declare client side actions.

Just some random thoughts about MVVM and JSF combined …

Short URL for this post: https://blog.oio.de/YwWMP
This entry was posted in Java EE, Java Web Frameworks and tagged , , , . Bookmark the permalink.

5 Responses to JSF and MVVM ?

  1. Stefan Frank says:

    Either that or jsf will just silently cease to exist: The more common pattern that is emerging here is a cleaner separation between client and server, with the client doing the heavy ui-lifting and the server just offering an API (be it RESTful or rpc’ish). Why should I have to deal with buttons, tables, links etc. on the server, keep track of which panel is opened, which tab is selected, which modal window has been shown? All I need are the deltas for my models, not the deltas for my gui.

    I’m just coming from a project that tried to blend/enhance richfaces/jsf with some more interactive client-side features: Keeping track of the state of your models in this hybrid became a major nightmare. Once you leave your clean, declarative jsf-world you’ll have to deal with all kinds of synchronization problems. Richfaces already has some ajax built in (so does icefaces and every other major jsf-implementation) but tying into this soon got messy: Just try to a reload once to see what I mean… These ajax-features even got some standard-love in jsf2.0 – but I don’t see a clear vision here where this is heading. It’s an afterthought, it’s messy and uncontrollable when demands on interactivity on the client grow: there is no clear API here how to tie this into JavaScript, just some clunky hooks. It feels like you’re trying to do surgery with boxing-gloves on.

    Better keep your server clean of all this widget-code. The server shouldn’t care how stuff is represented. I think the basic idea of representing widgets on the server is becoming obsolete. Instead, sharing models between client and server will be hot (or how nodejitsu calls it: Isomorphic JavaScript, http://blog.nodejitsu.com/scaling-isomorphic-javascript-code) If you’re stuck with java on the server, I expect more work in terms of model-mapping e.g. mapping jpa/validations into json that can be pumped into your gui without replicating code. Even generating both from a common model is feasible if you’re into MDD. If you truly accept that you’re GUI depends on javascript and ajax is here to stay, you will sooner or later have to accept that jsf is becoming extinct.

    • Thomas Asel says:

      Im not concerned of JSF to become extinct, its more like a tendency to underdevelopment. When it comes to client side, JSF really lacks on concepts and having the basic ajax mechanism standardized with and jsf.ajax.* is simply not enough. The problems that you described with Richfaces are a typical example, since there is no such thing like a standardized model for the client side. So developers have to dig deep in their chosen librarys implementation to improve things on the client side. Interaction with client side API’s will soon be very important (with HTML5 on the way), so next JSF version should take those aspects more into account. Unfortunately JSF 2.2 does not seem to focus on that: http://download.oracle.com/otndocs/jcp/jsf-2_2-edr-spec/index.html

      • edburns00 says:

        You are correct, we didn’t focus on that. Instead, we chose to add some hopefully useful features without changing the programming model radically.

        This blog entry explains that choice: .

        I was deeply impacted by all the bad press we received in 1.0 saying that we developed the spec in an ivory tower and didn’t listen enough to the community before producing a “standard”. This input informed how I approached JSF 2.0, which ended up being pretty well suited to the state of affairs when it shipped. Now, as Hr. Frank asserts, we have a different model where the UI state can more completely reside on the client.

        We’ve been watching and learning to see best practices emerge. I think it’s getting pretty close to the point where these standards can be codified into specifications. The think for IT Decision Makers to keep in mind is the ability of the Java Platform (via JCP) to preserve IT investment over time. This means both executable code, and developer skillsets.

    • Thomas Asel says:

      1.5 years passed since I posted this blog about JSF and MVVM. It seemed like a nice idea back then. The spec for JSF 2.2 evolved an improved a lot since then. Pass-through-attributes made it in the spec and enable not only HTML5 support (this was absoluteley neccessary) but also allow the development of advanced client side components. I really like the idea of using e.g. AngularJS within a JSF-component.

      So from a developers perspective, with JSF 2.2 we have all that is needed to create a MVVM approach, if desired.

Leave a Reply

Your email address will not be published. Required fields are marked *