Tuesday, December 30, 2008

Web User Interface Programming Thoughts

I've been thinking a lot about how we program web applications and user interfaces in general. There seems to be an extraordinary amount of repetitive coding and “boiler plate” code that we just ignore and assume that's the way it has to be. We spend little time doing the actual user-interface design because it takes so much time to just get a simple interface going and write all the supporting code. In my mind something conceptually simple should be simple to implement. For example, I want an ajax type paging grid with server side filtering using some data. Now this is a complex entity if you look at the details of its operation, but we shouldn't have to. We should be able to call a standard API and say “I want a grid here, connected to this data”. This is the path Adobe is going down with Flex and AIR. My question is how we can use similar technologies or develop our own libraries and standards to achieve this same effect?

One problem is in deciding how you abstract your interface through an API. This is further complicated by the layer at which the API works and how a toolkit renders. Let me try to illustrate what I mean with an example. Say I want to put a Date box in my page. Say we're using Dojo for implementation. If we write code using Dojo's API we'll have to follow a certain pattern. In this case, load the Dojo .js file, create our HTML node, and then load up the calendar by programmatically creating the widget or using the dojo.parser. Now what if we decide one day to switch to extJS. Now we have to rewrite all of that code, multiplied by the number of instances where we used it. So the sensible solution is to abstract the Date widget. Since we work primarily with XSL stylesheets maybe we'll create a template stylesheet that we import, than call a date template. Essentially we've just created an API. With this abstraction we have to decide on standard parameters that the implementation will need. How do we refer to the data in the request, we need to pass in the form name or id of some sort. What if we want to disable some dates, now we'll add another parameter. What's the syntax for a date range? Dojo can do this, but will other toolkits? What happens when switching implementations invalidates some of our API abstracting the implementation? Even more troublesome, what if we can't wrap a certain implementation because our API language (XSL) is incapable of processing the parameters and translating them? Even worse, say we want to use Flex, or GWT. They use completely different rendering pipelines that will be nearly impossible to implement with just stylesheets. Now we need to involve the Java layer (for GWT). So this xsl API would really only work for toolkits that can be initiated purely at the HTML layer.

We've revealed a sort of classic programming dilemma, one that I'm sure has a fancy name given by someone who thought about this before me. How do you abstract something as complicated as user interface widgets with an API and not be bitten by implementation eccentricities, limitations of the programming language your API sits in, or major differences in the approaches of different implementations?

If we step back, we'll realize that the problem is in where the API sits. The problem is in how the web rendering pipeline works. The current paradigm touts model-view-controller and separation of data from view. They claim that this separation occurs at the XML > XSLT stage, or even HTML > CSS. But this separation really occurs between the database and your web application programming language (Java in our case). Once you enter your app code, you inevitably affect the rendering and user interface. The app code controls your page state, your cache, your ajax servlets. It's impossible to do anything with ajax and not involve the app code. So your UI toolkit must interact with the app code and this is where your API abstraction must reside if you want to do anything as complicated as ajax.

This seems to indicate that GWT or Flex is really the right way to go. Maybe it's just too difficult to abstract your interface through an in-house API. Maybe you just have to pick a powerful toolkit such as these and be married to the implementation. And as long as these toolkits are designed to be themed and let you extend, and create new widgets, you should be able to achieve nearly everything you could want.