Oscar Westra van Holthe - Kind

Web framework abstractions

To date, there are literally hundreds of web application frameworks. Given the level of skill required to create a good framework, and amount of work that is needed to make it work well and have it sufficiently documented, it is silly to create a new one.

An overview of available web frameworks is hardly new. What I haven't seen however, is a comprehensive overview of the abstractions a web framework uses. This article attempts to provide that.

Abstractions

All frameworks provide abstractions. In it's most simple form, the Java Servlet Specification, the abstractions are limited to encapsulating the HTTP request and respons into objects, and calling the code that is mapped to the specified URL in the request. On the other end of the spectrum, there are frameworks that handle events, validation, specialized mappings between the view and the controllers, and even include database access.

It's worth mentioning at this point, that all abstractions leak. For example: the windshield of a car abstracts away the rain, but you still need to worry about aquaplaning. Therefore, you only want those abstractions that make your life easier. Also, given that many people have their own preferences with respect to accessing a database, I'll be focussing on only those abstractions that relate directly to a web application framework. Abstractions that you see in a full stack framework, but go beyond the processing of a request are not discussed.

Let's have a look at the abstractions I've come across:

Request & response objects (JavaEE)
The application server creates objects for you with which you can access the request from the browser, and specify what the response to the browser must look like.
Leaks: handling multipart/formdata requests and not being able to alter response headers after a certain amount of bytes have been written.
State handling / sessions (JavaEE)
The application server maintains a session for each browser, in which you can store data. The session is associated with each request using URL rewriting or a cookie.
Leak: if you store non-serializable objects in the session, clustered applications break.
Input conversion
The framework converts the browser's input into dates, numbers, and any other data type you want.
Leak: unless you're aware of this, you cannot display correct error messages.
Input validation
When your framework converts data, it implicitly also validates it. It's then easy to add a little more validations for required fields, minimum/maximum values, etc.
Leak: unless you're aware of this, you cannot display correct error messages.
External page references (Struts, Spring Webflow, ...)
The framework names each possible response from your code. Based on the response name, it then redirects/forwards to another page to display the result.
Leak: the names can break and are configured elsewhere. Also, if the code assumes a forward, the name may not be mapped to a redirect.
Output templates (Tiles, SiteMesh, ...)
Your pages will look alike because a consistent user interface is easier to understand for your users. A template allows you to define the common parts once, and reuse them. This is related to the next item.
Leak: The pages you build are not actual pages anymore, but page fragments.
Page components (JSP tags, JSF tags, ...)
Just like common layout elements, you'll also find you use common combinations of other page elements. page components like JSP tags allow you to name them and define them in one location. this helps to make your application consistent with more ease.
Leak: the tag is really a page fragment with variable scoping.
Windowed application like event handling (JSF, Wicket, GWT, ...)
The framework replaces the usual request/response cycle with events. When your code to handle an event is executed, you can query the screen objects (that have also been instantiated for you). This resembles standard windows programming, and as time goes by you'll have more and increasingly complex interface controls at your disposal.
Leak: You'll notice you don't have complete control over the page as soon as you need to add a simple, cutsom bit of Javascript.

Choosing the right abstractions

What team will have to work with it? is the first question to ask. Related questions are What's their experience? and What's required in terms of scalability, performance and functionality?.

Often, the best performance and scalability are achieved by using less abstractions. After all, each added layer of abstraction means more work the framework must do. But abstractions also make the work of a programmer easier (and software cheaper). Therefore, a classification of abstractions by their cost is useful. This is how I would classify them:

Light stuff
Only slightly affects the amount of CPU power needed.
  • Request & response objects
  • Input conversion (because you need to do this anyway)
  • Input validation (because you need to do this anyway)
Medium Stuff
Incurs a minor CPU increase.
  • External page references
  • Output templates
  • Page components
Heavy stuff
Incurs an increase in memory required, and a major increase in CPU required.
  • Windowed application like event handling (because each page is effectively built twice – to display and to get the values from)
Scalability related
Affects the amount of memory needed, as well as how easy it is to add more servers to handle an increased load.
  • State handling / sessions

In my opinion, to achieve a good tradeoff between performance and functionality, I'd only skip these abstractions:

Lastly, a few notes on component frameworks like JSF. Their defining characteristic is that they try to abstract the request-response cycle away ("Windowed application like event handling"). However, current implementations (mostly JSF) are expensive in terms of CPU&memory. Also, I find that in terms of ease of use, Microsoft's .NET framework is better than JSF.

In fact, JSF and it's like are mostly useful for low-skilled drag&drop developers; precisely the type of job that is increasingly often outsourced. And if you outsource it, why bother at all with the technical implementation?