Let them eat State

This post was originally published on the New Bamboo blog, before New Bamboo joined thoughtbot in London.


After getting a bit of feedback about my last post, I realised it may not be clear to people why I am advocating a move shifting application complexity into the client-side tier. Some of the points I am going to be looking at have been covered here, though this doesn’t expressly mention the role of state in all of this.

In the past, there has been a noticeable level of scorn for the “View” part in web-based-MVC architecture. Phrases such as “putting too much logic in the view” are often apt, but can be unhelpful when looking at the bigger picture. This has led to people trying to write UI code/behaviour from the comfort of their area of familiarity - Server code.

The main reason why I believe we (“Server-side” devs) need to rethink this attitude relates to statefulness.

State

Statefulness is something which exists in most Desktop applications, and means that you can essentially leave objects lying around in memory, and react to changes in their state via your UI. Most web-development doesn’t afford us the luxury that desktop UI designers have. HTTP is a stateless medium, which means we have to go out of our way to constantly persist and retrieve state from our persistence layer of choice (generally a RDBM).

The point here is that we tend to work only with representations of state, in the form of HTML, not the state itself. This makes building rich UIs more difficult. It is common for state to be picked out of the DOM using Javascript, but often this is wasteful.

While people are now moving towards more desktop-style applications on the web, I don’t think everyone is fundamentally re-examining what it means that we don’t necessarily have state.

It is worth pointing out that some web frameworks do offer statefulness, which generally means associating a given client to a particular server node so that the objects they are using can be readily accessible. This is not possible with Rails and many other common frameworks, and in many ways is not even desirable.

There are also other RIAs such as Flash and Java applets which have been holding State in the browser for years. Whatever the reasons (which I’m not going to enter into), these haven’t been widely accepted by all developers, and building interfaces in a combination of HTML CSS and JS is certainly the preference for us.

State vs Psuedo-State

Efforts have been made to give clients state, though not explicitly stated in those terms. It is common practice to use Ajax, for example, to send the contents of forms to the server, and refresh parts of the page with snippets of HTML. While this is going some of the way there, it still treats client-side code in a rather condescending way.

The following is an example of how RJS (do people still use this?) might allow a user to add a new todo item into a page without refreshing it:

page.insert_html :bottom, 'todo_list',  content_tag("p", "My new todo")
page.visual_effect :highlight, 'list', :duration => 3

This returns a mixture of JS to be evaluated, and HTML to be rendered, and so can only really be seen as allowing psuedo-state.

Developing a UI from the point of view of the server’s capabilities leads to misconceptions about what is possible, and leads to artificial constraints on what can be built. I believe that people spend a lot of time and energy trying to make a stateless medium (HTML pages delivered from a server), mimic a stateful one.

Javascript is a very powerful language, and can be given responsibility for managing a user’s state in their own browser. It reminds me of the charity adverts which run something like:

“give a poor starving person some grain, and they will live a bit longer; give them a combine harvester and they can do some fairly cool shit”

An example which allows for an intelligent client to control its own state might simply return JSON from the Ajax POST to create the new todo:

{:title => 'My new todo', :id=>2 }

Your client can then deal with this new data, and update the UI accordingly. Without labouring the point too much, this is the point at which you would start thinking about a a structure for dealing with updates to state.

The role of the server-side

There are people who may be uncomfortable with the change I am advocating, and a may cite duplication of logic as a reason not to endow client side code with the concept of models. I don’t really believe so, as there is plenty of logic which lies in the jurisdiction of the server, which you don’t necessarily want to be made available to clients. On a related note, though we are seeing front and back end code in the same language (eg. node.js), I don’t think that really matters and we aren’t going to see an abundance of re-use of the classes.

Server code can be geared towards it strengths, and essentially becomes a means of serving the platform (the raw HTML), and the JSON objects consumed by the platform. Its role is primarily reduced to:

  • Persistence
  • Validation and verification
  • Access control / Authentication
  • Serving HTML/assets
  • Marshalling and Transforming Data
  • Connecting to other services

There isn’t really much crossover in terms of the jurisdictions of the linked systems, and thus potential duplication and conflicts are likely to be minimal.

I hope that goes a way towards clarifying my increased emphasis on client code. I don’t think we should overlook the opportunities that introducing state creates. If you haven’t looked at my previous post, or didn’t see why it might be relevant, hopefully this will shed some light on the reasoning.