Programming
Article
By Harry Fuecks

MVC and web apps: oil and water

By Harry Fuecks
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

Roll back the clock by two years. That’s before AJAX, before Web 2.0, before Rails. Where were we then? Well pondering whether MVC was really such a good idea after all. Continuing from there…

What is MVC?

For a long answer, the best I’ve seen (for web heads) is Jeff’s analysis here. There more to be found via Wikipedia and yet more on the old C2 wiki.

A short answer, for web applications (with a PHP slant), is probably – a way to organise code based around the following ideas;

  • Model – those functions that wrap calls to your db
  • View – the templates / scripts that output HTML
  • Controller – the stuff that examines variables like $_GET and $_POST and works out what to do next

What’s important to remember is there’s no absolute definition of MVC and there are many grey areas for interpretation and yet more when it comes to using it online. That in itself means, if you’re building a framework, you just need to put the words “Model”, “View” and “Controller” in there somewhere and you’re probably as “right” as anyone else. A while back John Lim dared to ask Is MVC over-designed crap?, I suspect coming for the gut instinct of an experienced programmer. In a later update he wryly commented;

is MVC overdesigned crap? Well i was wrong about overdesign — it’s actually underdesigned. Is it crap? That remains to be seen.

Why MVC?

So why did MVC become a common pattern (or at least a common term) for web applications, bearing in mind it originally evolved for to help building desktop GUIs?

As far as I know it first showed in Sun’s Model 2 architecture somewhere around 1999(?) then crystallized into a specific (and popular) implementation: struts, around Y2K. From there, put bluntly, it seems to have become a self perpetuating mantra or tech lemming syndrome. It’s hard to find justifications of “why MVC” vs. any given alternatives, other than it’s not Model 1 (vanilla ASP / PHP would be regarded as Model 1). Most frameworks I see today advertise MVC without any indication of why they’re using it.

And lets face it: MVC sounds impressive (and intimidating) to people no in the know. What do we do when we see a term we haven’t come across before – search and find many other people saying “Yes MVC”.

So have we asked enough questions or have we just jumped on a collective bandwagon? Jeff in fact states the bandwagon factor clearly in the value of MVC – that there must be “something” in MVC because of demand for struts developers.

To me there’s a further red flag waving in that the classic hallmark of MVC in deskop apps where multiple, unrelated views that automatically updated given any change in the model (Jeff describes this nicely as the active model). Unfortunately, in traditional (as in non-AJAX) web apps, a view corresponds to a single web page response to a browser and within request-response protocol like HTTP, there’s no room for the server to instruct somer other browser window you have open that it also needs updating: web servers don’t contact you – you contact them. The hallmark of MVC doesn’t work on the web unless you hack some kind of client side refresh mechanism for check for updates. Could this be hint that MVC separation is not a best fit?

What I suspect is if we ask “Why was MVC chosen over [insert pattern here]?” loudly enough, the response will just be shuffling of feet and the occasional “Why not?”. Perhaps the guys that rolled “Model 2” might be frank – “We needed a pattern our (AWT / Swing) developer community could relate to and MVC was near enough. It wasn’t meant to be taken this seriously.”

All this is not to say MVC sucks and that you can’t built web apps with it. Just that I think we’re talking about square pegs and round holes. The real question is there a better way?

Alternatives

ASP.NET and JSF have both tried to bring Event Driven Programming to the server side, to mixed reactions. Given that we have enough miles on the ASP.NET clock now, the impression I get is experienced web developers are wary of ASP.NET because it’s “too smart” – the learning curve to mastery is significant and there’s perhaps too much clever stuff being done transparently in those web controls. ASP.NET is probably more pleasing to those coming from a VB6 background. Whether or not event driven programming is actually a competing paradigm to MVC is debatable but it’s probably fair to say it demotes the controller to a less significant part.

Meanwhile Coldfusion developers are still getting on fine with fusebox. ‘Nuff said.

Personally I don’t have anything specific to offer but rather more thoughts about how we got to MVC and specific issues with implementations. And I’m not ruling out MVC here, just questioning how it’s commonly being used.

Make Resources First Class

One issue I have with struts and derivatives is they promote actions as first class objects ( in Rails actions are class methods but I would still argue “first class”).

HTTP only has two actions (at least that are actually being used) – GET and POST – retrieve it or update it. At this point it’s worth reading Why Do Web Server APIs Suck So Much?.

To me a direct consequence of promoting actions as first class objects is we end up with people putting verbs in URLs like “http://example.com/item/1/delete”, which in turn leads problems like this and implies tight coupling (between client and server) and RPC. GET is clearly labelled as “safe / read only” while putting a verb in a URL implies something is going to be done (which may or may not be safe);

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered “safe”. This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

In a way it’s amazing that it’s taken until 2005 for us to collectively realize this stuff matters.

The other downside of putting actions first is I think it leads of counter-intuitive code, to all but hard core frameworkers. To most people the web means documents, pages, images, movies – stuff that it tangible and can be downloaded and stored offline – resources in other words.

So let’s make resources first class objects and have framework APIs reflect that. This is what REST is trying to tell us.

This might just mean finding smarter ways to write view centric code, emphasizing DRY while avoiding spaghetti – consider the “article.php” in this URL.

Alternatively it might mean we spend more time working on classes like;

class Joke extends Resource {
    function GET($Params) {
        # Return / display a joke
    }
    
    function POST($Params) {
        # Create or update a joke
    }
    
    function DELETE($Id) {
        # Delete a joke
    }
}

class Jokes extends Resources {
    function GET($Conditions = array()) {
        # Return / display a list of jokes
    }
}

Alternatively, for a really challenging point of view about putting resources first, you have to look at Wheat ( a prototype which sadly seems to have fizzled out, I would guess because the project objectives are at very high altitude );

Every object has a URI

And from the Wheat intro here;

I’ve been asked why does this warrant a new language (somehow no one seems to care about the new environment…). Here is one of my more wordy replies:

“There is no language today in which objects are conceived as the persistent, globally accessible entities that web programming today attempts to model. Web programming is sufficiently different from desktop and server application programming to warrant a new model: When building for those environments we expect programs to be started at a point in time, read the user’s data from some data store into the heap, process it, possibly interacting with the user, write it back and then quit. Heap based objects, or more generally, languages where the unit of operation is on ephemeral, memory based data, works perfectly for applications. When we think of web programming, we are trying to create a view where the user’s content is ever present, ever live, and widely accessible. Rather than build this world view up on top of an memory based foundation, Wheat has an object and language model that can directly support this style of programming.”

Scary! What if we really are all barking up the wrong tree? Perhaps there’s a relationship here to interest in closures.

Side note: would argue the content classes and objects in eZ Publish fit somewhere into the above description, being persisted in the DB.

AJAX and Forms

Imagine for a moment that AJAX really does turn out to be all it’s made out to be; that everyone has a browser that supports it, that they’ve left Javascript turned on etc. etc. Here we’d have an environment where MVC really could be applied correctly – something very close to the original fat clients MVC was intended for, but powered by Javascript, DOM and XMLHttpRequest.

So where would that leave the server-side? It pushes it down at least one layer, to become “back end” – the logical equivalent to databases in web apps today. You just want it to serve and accept updates to resources in a stateless manner – GET and POST.

If still you’re applying MVC on the server side, you’re probably keeping it as simple as possible, preferring to use strategy over framework. You’ve still got business logic on the server but controlling logic (including execution of workflows) has moved to the AJAX client. The server side has become a service layer I guess.

Side note:what activegrid seems to be doing with BPEL seems to be heading in this sort of direction, although it’s still server side technology. Within the activegrid “mindset”, PHP scripts are relegated (perhaps rightly so) to being “services”, just pumping text.

There’s also good chance you’re no longer generating forms on the server side but doing it dynamically with Javascript on the client side. Failing that, perhaps you’re using “standalone” form pages which are well seperated from your other resources. A “wizard” form, of multiple pages, no longer requires hidden input fields or otherwise but lives in the browsers memory as Javascript objects until the form is completed. If the elimination of form generation from the server side sounds far fetched, consider the precedent search box in Firefox (top right) – personally it’s been a long time since I looked at the search form on Googles home page.

What I’m really trying to say here is I think the desire for MVC on the server side is a result of obsessions with forms, limitations of Javascript, the desire to compete with desktop apps and that form method=”DELETE” never happened (so it was necessary to bundle this as another action via POST the action). You’ve got a button on your form called “Add To Cart” so you clearly want an AddToCartAction somewhere. With AJAX perfected, we’ll presumably be implementing our shopping carts purely client side, only getting back to the server again somewhere around the “Checkout” time.

RUD not CRUD

Perhaps another hangover from trying to put desktops online is talking about CRUD – four operations: create, retrieve, update, delete. With HTTP you only have three significant operations (one of which, DELETE, isn’t being used) – retrieve (GET) and update (POST): in particular there’s no distinction between creating and updating. That might sound like a trivial point, but there’s significance here that is being overlooked.

CRUD is defined in the context of databases where what you’re dealing with is sets of information – you need to make a distinction between inserting into the set and updating an existing member of the set.

Meanwhile HTTP was designed for access to resources, the “primary key” being determined by it’s URL (vs. having to worry about the insert id). If you think “documents”, it’s clear there’s no need to make a distinction between creating and updating – creating a document results in the first version. Updating means overwriting an existing document with a new version. But in both cases the client is POSTing the same thing and does not need to be aware of whether the document already existed or not.

Meanwhile a common first demo app for server side frameworks is a CRUD example. The implication here is frameworks place a strong emphasis on the database, while HTTP is largely ignored (it’s rare to even see HTTP status codes as a fundamental part of a framework).

Avoiding a long filesystem vs. database discussion (like the need for virtual file systems with extensible properties) suffice to say – consider how Dokuwiki stores wiki pages 1-to-1 as files compared to MediaWiki. What makes more sense to you? Perhaps our websites have been driven too far by the database?

The point here is, given the mismatch between HTTP and CRUD, we’ve put CRUD first which in turns makes actions first class in our frameworks. We aim to support N different types of action (verbs) when really we should have been dealing with only three – GET, POST and DELETE (the latter being perhaps re-routed to a specific “resource class” method according to some framework / form conventions).

Back to Beyond

Returning to this point, the conclusion today seems to be, rather than abandon MVC, abandon Java (or Perl / PHP / Python) in favour of a platform that reduces lines of code – “MVC with the least amount of pain please”. MVC is synonymous with our requirements for better web application development – “You want better practices? Use MVC”.

But what about extracting what we actually want as an independent list – forget about MVC for a moment? Off the top of my head (and not at all comprehensive);

  • Nannying: tell me how to get organised – clear signposts for where to put my code.
  • Just add water: give me my prototype now!
  • Don’t make me think: I can do this stuff even on my dumbest days.
  • DRY: making the same change 50 times is not cool.
  • Anti-pasta: help me avoid spaghetti
  • Security: no nasty surprises please. Help me get this right first time.
  • Testing: help me protect myself against myself.
  • [insert more here] x N

So far I haven’t come up with anything that can only be solved by MVC (and some have nothing to do with MVC at all).

Perhaps there’s a better pattern suited to the web? Perhaps the “controller” in MVC implies emphasizing “actions first”. If we demote actions in favour of resources supporting just GET, POST and DELETE, perhaps the controller is handled for us automatically by the framework?

Anyway, for lack of a better place to end this, a quote from The Register on Wheat;

And after the very first Sunday presentation, one audience member claimed he found the new web programming language Wheat “so beautiful, it’s made me cry!”

Login or Create Account to Comment
Login Create Account
Recommended
Sponsors
Get the latest in Front-end, once a week, for free.