Bio Keith Donald is the co-lead of Spring Web Flow with Erwin Vervaet and founder of the Spring Rich Client Project. Keith Donald is core Spring Framework project member and director with Interface21.
My name's Keith Donald and I'm best known in the Spring world as the lead of the Spring Web Flow project with Erwin Vervaet. In October we had a big milestone for that project, we went 1.0 final after 20 months of development and it has been great because in that period we had a lot of interest, a lot of usage, and that release was something folks were really looking forward to. It feels great to be here at the show to be talking about a final release of a product that we've been working hard on for a while. That is really innovative and is providing value to developers.
Spring Web Flow exists to solve one problem extremely well. And that's the problem of orchestrating control navigations within a web application. This web navigation is typically happening over a series of steps and they typically encapsulate some business task that the user is going to participate in. Web Flow focuses on that problem because if you look at a lot of the other frameworks that are available there isn't a lot of existing good solutions to that problem. When we started that was always our focus and that focus grew out of a need Interface21 had on a real project. The domain was extremely complex, the users of the application within that domain had to be walked through a rich set of flows manipulating financial information and data with a lot of dynamic navigation roles, back-forward had to work flawlessly and state had to be managed, server-side state. We were actually required to use Struts on that project but Struts really didn't have a strong solution for orchestrating and guiding users through very controlled navigations and managing the state associated with this navigation in the server. It was a clear opportunity for innovation and Spring Web Flow grew out of that need.
What we offer is a controller framework that allows you to develop these modules or flow definitions that are definitions of tasks that the user can participate in; representing things like applying for a loan, booking a flight, searching encyclopedia; any kind of use case that the web application can perform can be captured in a flow definition and we have a dedicated flow dedication language which provides a higher level abstract, almost a DSL for developing and writing UI flows, modeling dialogues.
This abstraction, this language provides that up-one level from the low level http building blocks world and provides an abstraction that allows developers to write their controller logic, test that controller logic without any dependency on any other technology because it is a very self-contained framework. Once that controller logic has been tested and you know your rules, your navigation logic for applying for a loan is sound, that logic can then be deployed and executed inside a servlet engine like Tomcat as part of a web application. Spring Web Flow ties into your most popular MVC framework like Spring MVC, Struts; we also have JSF integration.
It basically provides an environment for folks to model user interactions in a dedicated definition language, test those interactions and then think about plugging those in to their favorite web framework and we’ve seen productivity benefits there and the testability that our Web Flow enables and we've also seen leverage that our users got because once you got these workflow definitions they can run and execute these definitions in a variety of environments from Struts, Spring MVC, but also portlets as well. The same flow definition once built can be deployed within a server environment, in a portlet environment without any change.
With Spring WebFlow what we say is if you're experiencing some pain in a part of your web app. Let's say a lot of my app is a mix of free navigtation with a mix of controlled flows where the user has to be guided through a series of steps. If you're using Struts you may be experiencing some pain in implementing those control flows. I would say to a team: look at Spring Web Flow as an option for solving that part of your web application in an elegant way, plugging it in there. If you got new use-cases that have to be designed for using Web Flow, if they exhibit those kinds of characteristics where they basically guide the user through a series of steps towards completion of some task. I don't recommend "just go and rewrite everything and port everything to Spring Web Flow for example." We've certainly positioned the product where it's easy to introduce. There's a very low cost of adoption, it's very easy to configure.
If you’re experiencing pain, particularly with state management, with navigtatoin, solving the duplicate submit problem, solving the back button problem, we solve those problems out of the box and you can drop Web Flow in to model flows in your application and you get duplicate submit for free. You get post redirect for free, you get navigation roles that you can test outside of the container that you can then execute in a variety of environments, you get a lot of benefits. I see it as a great complement to existing technologies out there, with a potential to become more in the future.
Let's take Spring MVC for example. When a request comes in to Spring MVC, it comes into our dispatcher servlet. The dispatcher servlet then looks at a set of handler mappings to decide how to dispatch that request. And requests are dispatched typically to controllers and Spring MVC users can write their own controllers to define their own web behaviors. Spring Web Flow plugs in to that controller extension point just as another controller; so basically there's an adaptor between that exists that has knowledge Spring MVC and the Spring Web Flow bridges between the two systems. Web Flow itself is completely decoupled from Spring MVC internals, but that adaption piece enables the two to work together seamlessly. Bottom line is this: when the user in the url address bar hits a url and gets mapped to a flow controller, the flow controller consumes that request and looks for this: "what's the ID of the flow this user wants to launch?" It delegates to the Web Flow to say 'launch this flow definition". Or when the user is in a flow and they post back to resume paused execution (because they are participating in on-going conversation) the request goes back to the flow controller; he sees the post back and then delegates to Web Flow to actually do the resume operation.
There's a thin bridge between the two worlds and the same bridge is for Struts. So we have a flow action in everything in Struts. We have an action that bridges between the two systems and the same exists for JSF in a different way where we plug Web Flow in as a navigation handler. In all cases Web Flow remains this self contained component. It is a very self contained flow engine that you can just drop in whether it be inside Struts or Tomcat, or inside Spring MVC or JUnit.
The key abstraction in Web Flow is this notion of a flow definition. It represents a task that the user is going to be involved in. Let's take an order flow. What this is going to do is walk the user through a series of steps to build up information about the order. The last step is they are going to submit their order for processing or they're going to choose to cancel.
Web Flow allows you to model that order flow definition and when you do that you can say "when the flow starts, put an order bean, some kind of domain objects - in Flow scope. It is going to represent the state of this order task and when an execution of the flow is launched, Web Flow would care for managing that order object in its scope for the duration of the conversation. When post backs occur from the forms Web Flow would care for binding updates in the form fields to that order bean in flow scope. When you go back and forth Web Flow would care for insuring that the state is preserved, that you don't get browser warnings when you go back and forth.
Ultimately when you complete the task when you fill out all the order details and you submit your order, Web Flow will allow you to orchestrate the submit process and delegate into a middle tier like Spring- managed middle tier. When the flow ends all the state associated with the flow is automatically cleaned up. There's no need to worry about cleaning up session state that you typically have to worry about after a logical task completes within a web app. You model the task as a first class citizen and when the task completes the state is automatically cleaned up for you by the system.
Once the task is complete there's no way to resume the task as well so you get automatic state management - task complete, memory cleaned up - task complete can't go back and re-submit and that memory that is allocated during the course of task execution is typically allocated for you. You instruct Web Flow when to create a new order object. You instruct Web Flow when to bind to the new order object, when to update it, when to submit that order object to a service for processing. You don’t really have to go out and look those objects up from some external context from a session, from some other scope. It's all right there for you, inside the flow definition. I think that is unique. A lot of frameworks don't give you that kind of stateful model where you can just work with objects almost like local flow variables and those variables will retain their data for the duration of the flow. You don't have to worry about resolving them, looking them up, or worry about cleaning them up or worrying about thread safety issues or anything like that. They're just handled for you by the framework.
What happens is that user model flow definition. Then let’s say that they want to go test that flow definition so they launch an execution of that definition. When the execution starts it enters its first step, we call it "state"; in that step we're going to do some processing so we allocate some new state. We put some stuff in flow scope. We add some state of flow scope; the next step we're going to display a page to the user to participate in the flow. When the flow execution pauses and when the flow pauses it is stored into a repository where it’s persisted; there are various repository implementation strategies for state persistence. The default strategy stores a copy of the flow execution in the HTTPSession ultimately. That state is managed in the session and any tools or technologies that you have for session clustering or any kind of scalability at the session level apply because we're just piggy backing on standard session constructs at that point, for state management.
The state is there in the session and when the users are thinking about what they want to do next and they post back and they resume the flow, then the system handles restoring the execution from the repository ultimately from the session at the right point automatically, where an event is signaled to continue the flow from that point. That's one strategy.
We have a client based storage strategy where no state is on the serverside, all the execution state is written out to the client after each request, each time a Web Flow pauses and you can see that when you look in the source of the page and see this big long hidden key which is the embedded gzip compressed serialized flow execution key; in that case it is actually a stateful model in a stateless environment. There are trade-offs though; with the client strategy you've got more data to transmit, you got security issues and you might want to encrypt that key. It's interesting that the state management strategy is pluggable and we support several options from stateful side session storage to client side storage.
A lot of people think Web Flow means pageflow. In the early day of the project we said that Web Flow is a pageflow solution; that was a standard paragraph, a big picture of what Web Flow is about. I've changed that now. Web Flow is a focus user interface flow engine as opposed to a pageflow engine. What it really provides is a component model where the components are basically for modeling dialogues. How those dialogues are embedded within the application, that's up to you. A dialogue can be associated with the entire page area, or can be associated with a zone of a page, in a more ajaxian style where you're actually posting to a local zone a fragment of a page and updating that fragment partially to carry out some tasks with the user as opposed to refreshen the whole page.
We actually had a sample application called shipping rate that ships with the Web Flow distribution that demonstrates that approach. It uses Web Flow + prototype to just embed within the zone of a page/a flow. When they submit in that zone and an asynchronous request is sent to the server which is handed to Web Flow and then the content comes back and it updates that zone. That works really nice. We have some users going further than that and I think Web Flow's finding creative ways to combine ajaxian techniques with Web Flow is going to be an interesting area of innovation in the future.
We do a couple of things to solve that problem. If you're modeling a multi-step navigation you start on step one, you post, you go to step two and then go back, you typically get your browser's warnings because your browser is going to tell you "are you sure you want to re-submit this data that you just posted because this may have side-effects". Many of the users will get confused by this popping in their face. But then there's the genuine problem of maybe the post did have side-effects and you don't want to repeat that operation again. That's why the browser is protecting against that.
One of the innovative techniques that we have in Web Flow is this: since it exists at a higher level of abstraction we can do things like "before view is rendered as part of entering a view state automatically redirect first". When there's a post we do some operation and then we want to display the results of that operation; Web Flow automatically issues a redirect to a stable url to display the result which can be stable and refreshed; when you go back and forth now there's no browser warnings whatsoever. The developer who's writing the flow definition doesn’t even have to tell Web Flow to do this, it is just a default. When a flow enters a view state by default a redirect occurs every time and that enforces that best practice of post redirect get, it is just built into the framework automatically.
That's one way that we enable browser navigation without browser warnings; we protect against that. The other way is this: we have a well known concept called "web continuations" where as a user is being walked through a multi-step process we can actually take snapshots of the task - of what we call flow execution - at each step.
Let's say I'm at step one I go through it, now I'm at step seven and I want to go back to step two and continue from there. We can support that because we can actually snapshot the flow as it was -step 1, step 2 , step 3, step 4, step 5- and when they go back to step 2 they'll resume the flow from that point. They literally go back in time to the state of the conversation at that time and resume from there. If there were things that happen for example at step 3 and step 4 that actually needed to be redone and there were objects created that needed to be re-created they don't exist in step 2; we literally undo, go back in time to that point and continue from there. The state of the flow matches exactly what the client saw at that point; there are no issues where state gets out of sync.
We also have the ability to preserve - even if they go back and continue, there are two different options. Undone to match the state of the flow at that time or you can go back and still have state preserved. We support both options.
Bottom line with Web Flow is that when you write your flow definition you deploy for execution, you clickthru, you go back forward, back forward, while you're participating in this flow freely without browser warnings and with no issues. Once the flow is complete it's impossible to go back and continue from that point because we prevent flow that has ended can't be resubmitted, can’t be reposted. It's just built out of the box with that capability which just frees developers from having to worry about post redirect get and deal with browser navigation issues, state synchronization issues when they go back and forth.
It is going great. As early as preview 5 we've seen a lot of uptake of Web Flow. (preview 5 is an earlier release released in July 2005 and it actually had 13,000 downloads). I know a lot of folks are still using that release in production with a lot of success and are now interested in moving to 1.0 final. On our forums we've had over 7.000 posts from 1.000-2.000 different users; to-date (Dec 2006) we've had around 70.000 downloads of the entire product across the various versions and we've had nearly 10.000 downloads since we've released 1.0 in October.
In industry you're seeing adoption in a lot of different areas. There's a major travel booking site in the US that everyone knows and it is rolling out a Spring Web Flow powered version of their entire site in the second quarter of 2007 (I've learned about it at this conference; I knew I'd be supporting some of the developers working on that effort but it is great to hear that that's moving forward successfully. That's going to be a major success for the company. The European Patent office - which is basically the way you apply for patents wherever you live across Europe - uses Web Flow extensively. Web Flow is used within Accenture and they're having a lot of success with the usage of the product for their clients.
One of their clients (the US Postal Service) that I know has already gone to production and the project is moving forward smoothly. There are all kinds of adoptions in a variety of industries. When you go to a conference like this (The Spring Experience) you learn how folks are using the product and we're seeing a lot if innovation happening at these shops that are leveraging Web Flow; they're finding the product not only solid and natural to use, but natural to extend.
I was talking with one of the developer leads of that travel site. He has actually developed two separate extensions of the Web Flow that they are leveraging and expressed to me that the extra effort that Erwin and I and the rest of the team went through in making the product as high quality and as designed for extension as possible, has paid off there. It has enabled them to get a model they can build on to meet what they need to build. I found that really fulfilling. I think you're going to continue to hear a lot more about how Web Flow is used to solve problems for a lot of different folks in different industries.
Domain Driven Design by Eric Evans - I've read that book several times (it's a 500 page book) and I still pick that book up. It's one of those timeless books that you can read over and over again. I'm a really big fan of design patterns of OO. I love that paradigm. I'm a big fan of developing software that is elegant and looks elegant and is thought-out and putting extra effort into the effort quality over just the quantity. What Eric guidelines around building complex software in a way that still can manage that complexity. I found that very useful not only for engagements that I've had with clients but also for product development with Web Flow. I think a lot of domain driven design is reflected in the actual Web Flow implementation.