Monday, July 10, 2006

Spring Web Flow - A Declarative Web Controller Architecture

In the war for web application frameworks, the buzzword (or buzzphrase) is state management for conversational applications. Soon after JBoss released Seam, I had blogged about its state management capabilities using contextual components. At that point in time I did not have a look at the corresponding Spring offering and Keith was quick to point me out to Spring Web Flow, which also offers similar functionalities in modeling conversational Web applications.

I must admit that I am an ardent Spring fan, not because it is the most popular IoC container out there. The feature of the Spring application framework that appeals to me most is the non-intrusive / non-invasive approach which it evangelizes, encouraging developers to declare injection points externally into pre-built components, rather than forcing them to adopt their own. When I started digging into Spring Web Flow, I was not surprised that the same theme has been applied in this controller architecture as well. In fact, it is very well possible to implement a Spring Web Flow application without any Spring Web Flow specific Java code - it can be all POJOs injected via DI in user defined scoped flows and totally agnostic about the web stack above.

Flow is the King

When I started fiddling with Spring Web Flow, the first thing which struck me is the level of abstraction at which a Flow has been modeled. In a controller architecture, a flow has to be the central abstraction and all other functionalities revolve around a flow. Keith has expressed it so well in his blog :

Since a Flow is a first-class object (effectively an mini application module), you can interact with it, message it, store it, observe it, intercept it, etc. This is very much a contrast to traditional controller frameworks where there is simply no first-class concept of a "Flow"; rather, there are only a bunch of independent actions (or pages) whose executions are driven by the browser.

Technology Agnostic Abstractions

The abstractions of Spring Web Flow are not coupled with specific protocols like Http Servlet APIs. Instead they have an extra level of indirection in the abstraction layer, which makes integration with other technologies (like Struts, JSF and Tapestry) quite straightforward.

public interface FlowExecution {
  public ViewDescriptor start(Event startingEvent);
  public ViewDescriptor signalEvent(Event event);

public interface Action {
  public Event execute(RequestContext context);

In the above interfaces, ViewDescriptor, Event and RequestContext are top level abstractions which can be subclassed appropriately to provide specific implementations. This is a big deviation from JBoss Seam's philosophy, which has tied the latter to EJB 3.0 and JSF - no wonder Gavin's initial intuition is that that two models simply don't make sense together.

Continuations based Flow Control

SWF offers continuations based flow control for conversational applications. This implies uniform handling of browser navigation buttons, simultaneous multiple conversations and a cool transparent Strategy based flow execution storage - all out-of-the-box! Again, what I like on this continuation support is that Spring provides the correct level of framework abstraction. The purpose of Spring is not to provide a full-blown continuation framework (like Rife, which has a different purpose in life) - SWF provides continuation for DSL based flow execution, upon which a snapshot can be saved and restored at any point. This is a clear decision that avoids over-engineering, or as Bruce Eckel would call Framework-itis.

OTOH conversational states are managed in Seam using stateful session beans and what Gavin calls Subversion of Control (Bijection = Injection + Outjection). It is an alternative approach to what SWF offers. However, I find the SWF model more intuitive to address the cross cutting concern that conversations offer.

Other Cool Features

Apart from the above specials, you have lots of cool stuff up for grabs in SWF. Here are a few samplers which caught me :

  • Conditional Transitions as part of the flow control DSL, along with a pluggable TransitionCriteria abstraction.

  • Solid support for wizard style flow cases.

  • Flow-By-Contract - support for enhanced flow lifecycle callbacks through an Observer based listener interface. You can drop-in pre-conditions and post-conditions with invariants for the flow to pass through that state.

  • Reusable sub flows as a separate abstraction.

  • Bean method binding capability while modeling your flow action.

  • Transactional Web Flows - no more hell with tokens to prevent duplicate form submission. And best part is that it works transparently for flow conversation snapshots as well. All you have to do is to turn on the transactional property in the web flow declaration in your DSL.

  • Strategy based state exception handler which u can plug in to your web flow declaration.

The distribution of SWF comes with a rich set of examples, which amply demonstrates all of the above features. The sellItem example is the richest one and has all of the killer features demonstrated. I fiddled with the distribution for a week (not as part of my regular day jobs, though) and have come across the above cool stuff. On the whole it looks to be a regular Spring delivery - framework based, patterns enriched, easy-to-use and above all, non-invasive (according to me, the coolest aspect of any Spring component).


Keith Donald said...

Thanks for the kind words!

Just a few notes--the latest version of Spring Web Flow is 1.0 RC3, which we consider fit for production use.

You will definitely want to use 1.0 RC over say 1.0 EA or PR5, as the APIs have changed on the road to 1.0 final (I noticed a few of the referenced APIs in your article were PR5 versions).

We will release Spring Web Flow 1.0 final the same day Spring 2.0 Final, which is targeted by the end of July.



Unknown said...

[keith] I noticed a few of the referenced APIs in your article were PR5 versions :

Actually I used an earlier version which I had downloaded. But the main focus of my post was to appreciate the architecture of SWF - it nicely gels with the theme of Spring (DI) and non-invasive, as usual. Anyway thanks for pointing me to SWF in the first place - I now know what to recommend as part of the Java EE 5 Web stack.

Keith Donald said...

Indeed; flexibility in configuration [with intelligent defaulting], non-invasiveness, and a promotion of separation of concerns via proper application layering are central themes of Spring Web Flow.

Yes, exactly, Spring Web Flow "flows" are self-contained controller modules that may bind directly to your domain layer without coupling your domain-specific code to Spring or Spring Web Flow APIs. And yes, flows can be combined and nested to orchestrate complex user interactions with browser navigation support, automatic state management, and duplicate submit prevention.

We've got some interesting ideas for 1.1 as well, btw. I'll be sure to keep you posted.


Anonymous said...

Wanna expand without any hassle? Hire a KPO.

Whether You Want …
To expand without any hassle?
Temporary employees who are ready to work around the clock?
To minimize management hassles?
To increase your profits with reduced cost?
Then it’s time to search for an IT outsourcing / KPO company in order to achieve all above positive aspects.

Your search ends here at interactive web connects…

Comprehensive range of KPO services
We try our best to strengthen your customer interaction using variety of web tools. We specialize in supporting your company

at back end in efficient way. Many companies are outsourcing their support work to us, Try us once and see the difference...

Interactive Web Connects