Skip to main content

Extending the Web with JSF

Posted by jhook on March 4, 2006 at 2:05 AM PST

Background

In a previous blog, "New Feature for JSF 1.2", I concluded with a few sentences on breaking through traditional MVC with JSF:

At the 30,000 foot view, here we've broken through the traditional URI/resource in request/action based frameworks such as RoR, where each thing you want to partially handle has to be separated out and coordinated as a specialized endpoint. Not so with JSF since we've extended the concept of a URI into the page itself, allowing you to uniquely operate on resources embedded into the page. The best part is that your components don't need to know that they are processed as part of a whole or part. In truth, the same applies to your domain model-- refresh that list of employees or modify just one employee without needing to coordinate actions or special cases.

Let me elaborate on this a bit in relation to where I see JSF progressing through JSF 1.2 and future specifications. Keep in mind, I'm only one EG member with my own views. First, it'd probably help to explain the what's different about JSF in relation to other, common MVC implementations available.

Traditional Action Frameworks

  • Requires each request to be coordinated and written as a special case to maintain state.
  • The Java code in the Action serves to deal directly with the HTTP protocol in whatever facade.
  • Java code in the Action pushes possible content to a separate view.
  • Actions must manually handle protocol state transfer to the business model
  • Requires a view to be written for each case to supplement what's coordinated in the actions. Usually in a 1:1 or 1:many relationship for actions to views.
  • Low levels of reuse in both the Java code in the Actions and View
  • Minimal network/server overhead since developers are required to code/optimize each possible request/response condition.
  • Examples such as basic Struts, straight Servlet/JSP, many many others.

Hybrid Component/Action Frameworks

  • Still requires each request to be coordinated and written as a special case to maintain state.
  • Introduction of component-like concepts eases supplementing the view.
  • Usually have a single event system (request)
  • Components help promote re-use, but there's still a 1:1 or 1:many relationship between actions (or pages) and views.
  • Components/Actions/Pages often require explicit reference to model artifacts, degrading runtime agility during development.
  • Additional network overhead since often times these frameworks make some accommodation for stateful components.
  • A lot of the newer frameworks fall into this category.

Component Frameworks

  • Framework controller interacts directly with component artifacts.
  • Components act more like a compositional Action or Page from hybrid/traditional MVC.
  • Components and their structure become stateful, adding more network overhead over hybrid solutions.
  • Multiple events are coordinated over component trees.
  • Removing the 1:1 or 1:many association between actions and views, now it becomes many:1, flipping roles.
  • Components are self sustaining, which can be evaluated by themselves or part of a larger view.
  • Since components are stateful, model is usually dynamically referenced, allowing it to change or modified independent of the view at runtime or in development.
  • An example is something similar to JSF

So What?

I thought you'd say that! I believe a deficiency in many MVC solutions is that at some point, you are required to supplement the framework with action or page artifacts in order to coordinate request processing. With Component Frameworks, the view becomes self sustaining for request processing via declaration. With this, we've flipped the traditional 1:many role of actions to views in development and we now have a many:1 relationship. This seems to be more natural to developers for handling event systems instead of coding handlers (actions) for each possible event in the application.

To circle back on my original point of this blog, because components are self-sustaining within the framework, this provides the aforementioned benefit of flipping action and view relationships and allowing your documents and views to be processed as a whole or as partial fragments. Traditionally, since MVC events are mapped via URI as a special case-- that's one channel of communication. With component frameworks, a single URI can be processed/handled in multiple ways in part or in whole, which leads the way to richer forms of communication on the web while easing development.

Take a look at what would be required for development, keep in mind, what is categorized as an 'action' is java code that only exists to coordinate event or request processing of state.

Traditional MVC Component MVC

For traditional MVC each possible event from the view, you've been required to develop and maintain an endpoint that often includes one more artifact that supports rendering (a view). On top of that, the coordination between client and server is only supplemented by convention and is not automatic. With component frameworks, your development time is spent producing a single artifact that describes the view, composed of pre-fabricated and reusable components that automatically coordinate client and server communication.

As we push forward into richer client interactivity, AJAX for one, what expectations are going to be put back on the developer for not only coordinating, but maintaining these specialized solutions? By the nature of component MVC, each component handles it's own state coordination as supported by the overall framework. This means that components can encapsulate handling AJAX or other rich-content delivery without concerning the application developer or other components included in parallel-- 'they just work'.

How Practical Is This?

It depends on what kind of scalability you are looking for. It's like the old project management grid, the division of: time, money, and quality. You can't have everything-- yet. What I'm talking about is scalability of requirements vs. hardware/bandwidth. I jokingly remember when Struts first came out and people asked about the additional overhead on hardware, Craig replied something along the lines of, "Hardware's cheap, you can always add more, programmers and application maintenance is what's expensive." While this is true, everyone knows there can be restrictions.

Traditional MVC Component MVC

The above graphs only serve to highlight differences between the two routes of development.

Vertical Development

One may retort, "Why do you think component frameworks are much better at scaling complexity?" To avoid sounding like a broken record, let me ask why everyone uses Spring. Spring provides a series of pre-packaged, pluggable artifacts that support development on the JEE stack. Components work the same way. I could, for example, provide a component that generates an editable table, backed by EJB 3. Similar to portlets, a developer can drop components into their application and use in parallel with others. It's a vertical solution such that it doesn't require much, if at all for additional development.

Pre-packaged solutions aside, since component artifacts are self sustaining, so are developer-created supplements that increase maintainability and re-use. The solutions are vertical.

With traditional MVC, you end up with a series of horizontal solutions that must be maintained and coordinated across multiple layers. The EJB-backed table example would probably require: directly interacting with a PersistenceContext, generating actions for each event type, manually coordinating state transfer between the client and the server, and creating a view to handle passing the appropriate state to the correct actions. On top of that, could you ever use all of those artifacts along side other widgets in a larger view? You can quickly realize the exponential growth in complexity for development with traditional MVC.

Gravity Kills

So you've warmed up to the idea of component solutions for MVC, but the stateful overhead gives you chills. Well, to do component solutions correctly, you are going to have some additional overhead. Really, are you supporting a few hundred users or tens of thousands? If it's the latter, I have an answer for that (surprise). Just like with ORM solutions for persistence, there's cases where you need to optimize. Nothing would stop you from dipping into SQL queries or direct JDBC use. Well, with component frameworks, there's nothing stopping you from either marking components transient or basically limiting their use. For those 'dump content to screen' use cases, you may not need any components at all-- thusly a lack of overhead where the calls could be stateless. But for those cases where things start to get complex, go ahead and utilize components to support development.

Basically, it's a major misconception that because you use components, everything must be coordinated via components. As mentioned in previous blogs, you can produce/render URLs that simply pass identifiers without requiring component state to be maintained across requests.

Why Choose JSF?

First, it's a standard. While some may simply ignore this fact, it's already blossomed a large market of solutions/services. This is Web 2.0. You have multiple vendors, shops, and open source projects that can be literally dropped into and utilized with your applications. While other frameworks do support component development, no where else are you seeing this kind of support from the community at large.

Look at JSF's track record. JSF is built more like a platform, allowing extreme amounts of customization. Since it's initial spec, we've seen many alternatives pop up for describing views, managing application state, and tying in existing popular frameworks. I could start a list, but again, no other framework on the market has been as actively customized or added to-- including Struts.

Finally, look at the way you develop applications. It's the interface/UI that sells your product or more commonly sells your capabilities as an application developer. Going the route of components, knowing you can more easily scale UI complexities-- you're not going to be selling yourself short.

Related Topics >>