Big picture thoughts on software and other topics

June 19, 2009

MVC - The Anti-Controller Revolution Heats Up!

by Brian Donahue

In February of last year, I posted my thoughts on current MVC abstractions in Rails, and .NET, and how I felt that Controllers were really just glorified namespaces, where related action methods sit.  This leads to a lot of pain in separating concerns, routing flexibility, action reuse, etc.  In JP BoodhooBroken Link: http://blog.jpboodhoo.com/'s course (the first time I got to attend, in October 2007) he showed a simple example of a "FrontController" model where a single application controller handled all requests and routed them to an appropriate command object.  In that scenario, "Actions" are separate classes, and therefore become first-class citizens.  This really appealed to my Object-Oriented aesthetic, because if a Class is supposed to be a cohesive unit, even the most cohesive Controllers are only bound by the "resource" they represent, such as a ProductController and its associated CRUD actions.  Each action on a controller can (and often does) have its own set of dependencies and concerns.  Why not just group by folder or namespace or some other way of grouping related Action classes, rather than as methods on a controller?

Recently, several folks that are smarter than myself have started thinking about this.  I first noticed Jimmy Bogard making a few comments on Twitter about it that echoed my thoughts very closely.  Then, this ringing endorsement from Jimmy must have prompted Chad Myers to write a nice summary of the idea on his blog.

I’m really looking forward to what the community comes up with here, and hopefully I may even be able to contribute something.  FubuMVCBroken Link: http://code.google.com/p/fubumvc/, Chad and Jeremy MillerBroken Link: http://codebetter.com/blogs/jeremy.miller/'s (and other contributors now) open source MVC framework has a lot of incredible ideas in it, though it’s still in progress, and perhaps too architecturally advanced for even the mainstream ALT.NET community (there are a lot of advanced C# techniques and some very academic-sounding naming strategies that I could see frightening away all but the most ambitious of programmers/teams).  I’ve been toying with the idea of building my own controller-less framework, and have taken a couple stabs, and often used FubuMVC as a reference for some pieces.  So far, I haven’t really fleshed out my ideas to be useful enough for anyone else though.

What I had come to believe is that unlike JP’s model (at least as I last saw it in November 2008), it seemed that mapping a request to one action was still not an optimal abstraction.  I based this on two basic scenarios, though I’m sure there are more.  First, requests with the same url and/or post data may require different responses dependent on whether the client was a browser, a mobile browser, an API call (expecting JSON/XML), etc.  In this scenario, you could use the same command to return the ViewModel data, but any number of "Response Commands" could be used to render the data in the appropriate way for the client.  Secondly, there may be distinct view logic that needs to occur, for example, when rendering a view for a browser, permissions, localization, and other user-specific customization may need to occur, where as returning pure data to an API call may not require any of that logic.  It seems to me if you include all this rendering knowledge along with the actual "business" of the request into a single command, you’ve only taken a baby step beyond the Controller/Action paradigm.

In Chad’s post (read it now, if you haven’t yet!) he talks about mapping requests to a group of commands, or command chain.  This takes my idea of separate Request and Response commands a step further, and I think it is probably a better idea, and could open up a huge opportunity for very succinct commands that are triggered by a request, of which some could be asynchronous, synchronous, etc.

I’ll be watching this closely as it progresses, and hope that we can make writing web apps easier, cleaner, and more testable for all of us soon!