The other day, DHH[1] tweeted this:
Forcing your web ui to be "just another client" of your API violates the first rule of distributed systems: Don't write distributed systems.
-- DHH (@dhh) June 12, 2012
In building the new Basecamp, 37signals chose to do much of the rendering on the server-side and have been rather vocal about that, bucking the recent trend to build really richly interrative, client-heavy apps. They cite speed, simplicity and cleanliness. I quote DHH, again:
It's a perversion to think that responding to Ajax with HTML fragments instead of JSON is somehow dirty. It's simple, clean, and fast.
-- DHH (@dhh) June 12, 2012
Personally, I think this generalization is a bit short-sighted.
The "rule" that is cited in the first tweet about distributed sytstems is from Martin Fowler who says:
First Law of Distributed Object Design: Don't distribute your objects!
So, yes, duplicating state into the client is essentially just that: you're distributing your objects. I'm not saying I'm wiser than Mr. Fowler, but I do know that keeping client state can make an app much more useful and friendly.
Take Path for iPhone. It caches state, so if you're offline you can read posts from your friends. You can also post new updates while offline that just seemlessly get posted when you're back on a network. That kind of use case is simply impossible unless you're willing to duplicate state to the client.
As application developers we're not trying to dogmatically enforce "best practices" of computer science just for the sake of dogma, we're trying to build great experiences. So as soon as we want to support that type of use case, we have to agree that it's OK to do it in some circumstances.
As some have pointed out and DHH acknowledged later, even Basecamp goes against his point with the calendar. In order to add the type of user experience they want, they do clientside MVC. They store some state in the client and do some client-side rendering. So, what's the difference in that case?
I'm not saying all server side rendering is bad. I'm just saying, why not pick one or the other? It seems to me (and I actually speak from experience here) that things get really messy once you start mixing presentation and domain logic.
As it turns out, Martin Fowler actually wrote A WHOLE PAPER about separating presentation from domain logic.
The other point I'd like to make is this: What successful, interesting web application do you know/use/love that doesn't have multiple clients?
As soon as you have any non-web client, such as an iPhone app, or a dashboard widget or a CLI or some other webapp that another developer built, you now need a seperate data API anyway.
Obviously, 37signals has an API. But, gauging by the docs, there are pieces of the API that are incomplete. Another benefit of dog-fooding your own API is that you can't ship with an incomplete API if you built your whole app on it.
We're heads-down on the next version of And Bang which is built entirely on what will be our public API. This re-engineering has been no small undertaking, but we feel it will be well worth the effort.
The most interesting apps we use are not merely experienced through a browser anymore. APIs are the one true cross-platform future you can safely bank on.
I'm all ears if you have a differing opinion. Hit me up on twitter @HenrikJoreteg and follow @andyet and @andbang if you're curious about what else we're up to.
[1] DHH (David Heinemeier Hansson) of Ruby on Rails and 37signals fame is not scared to state his opinions. I think everyone would agree that his accomplishments give him the right to do so. To be clear, I have nothing but respect for 37 Signals. Frankly, their example is a huge source of inspiration for bootstrapped companies like ours at &yet.