Server MVC and Solving the Wrong Problem

TL;DR MVC frameworks provide infrastructure to solve make believe problems. They complicate what should be simple.

Update (Feb 4, 2016): While writing this post focused on server-side MVC, I came across a somewhat related post, Why I No Longer Use MVC Frameworks, discussing problems with MVC on the client-side. It follows a slightly different direction and is well worth your time.

Background

In 2014, I presented a talk on F# on the Web at many user groups and conferences. One of my primary goals for the talk was to talk about F# adoption at Tachyus and show off just how easy it is to use F# for web development. After I presented the talk at CodeMash in January 2015, I put the talk on the shelf.

By January 2015, I had started contributing to Freya with Andrew Cherry and wanted to push the web machine-style approach, which I’ve found to be a far better solution. In the meantime, at Tachyus, we started using an in-house tool called Gluon, which generates a strongly-typed (and tightly coupled) TypeScript client for F# API definitions. These different approaches kept bringing me back to thinking how poorly the MVC paradigm fit server-side applications.

Model – View – Controller

With MVC, you are supposed to separate Models, Views, and Controllers. In most web MVC frameworks, models relate to some materialized version of your data store plus additional DDD or other machinery. Views are represented as HTML and, perhaps, ViewModels, though some like to lump ViewModels in with the Model piece of the puzzle. Controllers are almost always a replica of the RESTful Rails Controller pattern, a class containing methods the represent endpoints and return Views. For the purposes of our discussion, let’s assume that a View may be any serialization format: HTML, XML, JSON, etc.

Aside: I’m aware I just lost some of you. HTML as a serialization format? Yes, it’s just declarative markup and data, just the same as other XML, JSON, etc. formats. That it may be rendered by a browser into a user interface is not relevant, as many applications I’ve seen do use HTML as a data communications format b/c of its hypermedia support.

I think it’s worth noting that MVC started life as a UI pattern in Smalltalk. There was no server in sight. Stephen Walther wrote about The Evolution of MVC at the advent of ASP.NET MVC. If you are unfamiliar, please read it, and I’ll spare you my rendition here.

We’ve already uncovered that we have at least one rogue element floating around in our pattern: the ViewModel. “But wait; there’s more!” We can’t forget the real controller of our application: the Router. The Router is really like a Controller since it intercepts all incoming requests and dispatches to appropriate handlers. And this is really where it starts to break down. Note the terms I just used. I didn’t use “route to controllers, which then determine the appropriate methods to call.” I used entirely different terminology. If you break down most of these MVC frameworks, you will find something similar: a meta-programming mechanism for deconstructing all these pattern artifacts and turning them into handlers available for dispatch from the router. Don’t believe me? Look in your call stack the next time you debug one of these applications. You’ll see a glorious stack of meta-programming calls instead of the few, clean calls to your class-based implementation.

 

Router – Handler – Formatter

Let’s switch to the terms we actually use in describing what happens. I’ve listed them in the order they intercept a request, though we could switch them around and list them in the order in which they return a response. Isn’t that interesting? These pieces actually form a pipeline:

Request -> Router -> Handler -> Formatter -> Handler -> Router -> Response

This pipeline is listed in terms of handing off control. Most likely, your framework is tuned to let the Formatter write the formatted response directly back to the socket. However, many frameworks, such as ASP.NET Web API, let you return a value that the framework will later serialize and write to the socket. In other cases the framework may buffer the socket actions so it can intercept and manipulate headers, etc.

Router

As I was building the presentation I linked above, I started writing minimal implementations of web apps in F# for TodoBackend, a site showcasing server-side Todo application APIs. I wrote examples in ASP.NET Web API, a little DSL I wrote called Frank, and an implementation using only the Open Web Interface for .NET (OWIN). The OWIN implementation was intended to show the maximum LOC you would have to write. I was surprised that it was rather close to the other implementations, longer by only 30-40 LOC.

The OWIN implementation surprised and delighted me. I was amazed at how simple it was to write a for-purpose routing mechanism without a proper Router implementation. I had built a light wrapper around the ASP.NET Router for Frank, but the combination of F#’s Active Patterns and System.ServiceModel.UriTemplate provided a nice, explicit, and still comparatively light and powerful mechanism for composing a Router.

Aside: Please note I’m not stating we should absolutely throw away all routing libraries. I merely want to point out that 1) what we are doing in web applications is primarily routing to handlers and 2) routers are not all that complicated, so you shouldn’t think you _need_ a routing library.

FWIW, were I to recommend a routing library to F# web developers, I would suggest [Suave](https://suave.io/). I’ve really come to enjoy its flexibility.

Handler

We’ve covered the non-MVC part of MVC frameworks. What about the others? I’m not entirely certain about the Model aspect, to be fair. I think the ASP.NET MVC team took a good approach and left it out of the core, which is interesting in that they really provided a VC framework. Already the “MVC” pattern has broken down.

What about Controllers then? Controllers are typically classes with handler methods, as we said above. There’s that Handler word again. It’s worth noting that the core of ASP.NET contains an IHttpHandler interface that ASP.NET MVC builds on, as well. So let’s take a deeper look at a Handler, shall we?

The simple OWIN router I showed above calls simple functions. Here they are:

If you were to ignore all the machinery built into Controller base classes to support the meta-programming-heavy MVC pattern, you would find something like this at the bottom of the call stack. Ultimately, you need to pass in some things from the Request, look up some data, transform it to a representation, and return it with headers, etc. It’s all relatively simple, really.

However, there’s a trade-off to using simple functions: they are now easily re-used in different parts of a router. I don’t particularly find this a problem, but if you were to shove hundreds of these functions next to each other in a single file, you might run into a maintenance problem since the function signatures are almost all identical.

I think the class-based approach has some nice benefits, though, I do prefer the function-based approach. With a class, you can collect related things together and take advantage of compilers to prevent re-using the same method name with similar parameters. Unfortunately, almost all real MVC frameworks work around these potential safety measures with their meta-programming capabilities and use of attributes. Oh, well.

Aside: I’m sure some of you are wondering about the model binding support that turns query string and form parameters into typed arguments. I don’t really know where those fit in this, so I’m adding them to this aside. While model binding seems to work okay, I can’t think of an application where I didn’t run into problems with it. I found it easier and hardly more effort to manually deserialize query strings and payloads using simple functions. These are often quite easy to reuse across multiple handlers/controllers, and you again gain explicit control. YMMV.

Formatting

Formatting, or rather Content Negotiation, replaces the view layer. HTTP stipulates that the server returns a Representation of a Resource but not the Resource itself. In the case of a file, the Representation will likely be a copy. In the case of a dynamically generated response, the Handler serves as the Resource responds to a request using a formatter to render the requested output. While the most common response used to be HTML — and thus a View — many responses now return XML, JSON, or a myriad of other formats. Picking only one may be a pragmatic choice, but it’s really limiting in a framework. Note we have not even addressed the various special cases of JSON and XML formats that provide more meaning, links, etc. and don’t work with any one formatter.

Then again, you’ll find times when a single format and a general serializer is all you need. The example app I’ve described above serves only JSON and has serialize and deserialize functions that just call Newtonsoft.Json.JsonConvert:

What happened to all my talk of Content Negotiation, etc? It’s still there. Were I to realize I needed to support a client that wanted XML, I could add a pattern match on the Accept header and call different formatting functions. But why bother setting up all that infrastructure when I don’t need it? I’m not arguing for an ivory tower here. I just want to point out that HTTP supports this stuff, and MVC does not.

In short, formatting is an area that often severely limits a framework’s flexibility by choosing to make easy a few blessed formats and mostly forsaking the rest.

I think it’s also worth noting that writing a general-purpose serializer is difficult and requires a lot of work. Writing a bit of code to generate string formats from known types requires a bit of boilerplate but is rather trivial.

Conclusion

I want to make it clear I’m not trying to dump on all frameworks. While I do prefer composing applications from smaller libraries, I think frameworks can be very useful, especially when properly used to solve the problem for which the framework was designed. However, the MVC style frameworks fell off the rails (pun intended) long ago and suffers from a poor abstraction layer. A pattern or framework should provide abstractions that relate to their domain and solve common problems. Re-purposing a pattern name because it has some popularity is asking for trouble and will ultimately prove limiting. MVC is the reason so many people think of HTTP and REST as a form of CRUD over a network connection and have little to no understanding of the richness of the HTTP protocol.

MVC does not fit HTTP.

Image Credits: ASP.NET Web API Tracing (Preview) by Ron Cain on his blog

Advertisements

The Real MVC in Web Apps

I recently stumbled across Peter Michaux‘s article MVC Architecture for JavaScript Applications. I’ve followed Peter’s writing in the past and was surprised I’d missed that and several others you can find on his site, including the more recent Smalltalk MVC Translated to JavaScript. (While you don’t have to go read them now, I recommend you do so.) Peter focuses his attention on JavaScript applications. I’m going to extend this a bit and tie in a bunch of other things I’ve been reading to show that 1) the current trend appears to be heading back in this direction (albeit under different names) and 2) that MVC need not focus entirely on the client side.

First, though, I should establish that I think the use of “MVC” to describe server-side frameworks is a complete misnomer. (I’ve written about this previously.) The “MVC” claimed by Rails, ASP.NET MVC, and others is based on Model 2. While visually related, the reality is that they have very little in common since “Views” are mere templates and not the component object originally used in Smalltalk’s MVC (see Peter’s articles above).

Background

About a year ago, I was building SPAs with AngularJS when I came across this post from David Nolen: The Future of JavaScript MVCs. I’d heard and enjoyed David talking about Clojure at LambdaJam earlier in the year, so I paid attention. At that time, I’d not yet heard of React, but I quickly started looking into it. React claimed to offer a paradigm that more closely matched functional programming; an attractive feature for an F# developer such as myself.

At that time, I still hadn’t really thought through exactly why I was building apps the way I was building them. Clients liked the perceived responsiveness in SPAs, and that was sufficient reason, despite some of the complexity involved. Also, AngularJS had, to that point, been a perfect fit for many of the forms-over-data style apps I was writing, and though I was uncertain about mixing binding logic into my markup, I’d started accepting it as the way forward.

When Facebook announced Flux, I was a bit more excited, as I liked the single-direction flow, though I thought some of the pieces in their pattern were a bit much. Around that time, I also found mithril, which looked like a nice mix of AngularJS and React with potentially better performance and a smaller footprint. Nevertheless, I stayed the course with AngularJS, as I needed a really good reason to switch frameworks.

A few months later, we picked up Kendo UI in order to use some of its components in our app. At that point, and combined with some limitations I ran into with Angular, as well as its learning curve preventing other team members from quickly contributing to our front-end app, we made a decision to start moving away from Angular. We have not made a furious effort to do so, and we have not selected a new framework. We may not.

As I was investigating potential target frameworks, I stumbled across the Futurice article Reactive MVC and the Virtual DOM and shortly thereafter was told about Reflux. While almost entirely the same thing, the former espoused that it was roughly equivalent to MVC, while the latter claimed to “eschew” MVC. Which was true?

I then stumbled upon Peter’s articles, as noted above. Indeed, both Reflux and the Futurice MVI approaches are rough equivalents of the classic Smalltalk MVC with the additional constraints of each component communicating only in one direction. In the Futurice case, MVI also makes all pieces observable, not just the model and simplifies the Controller to a UI event to domain event mapper, more or less.

Model-View-Controller and OOP

Hold on a second. Isn’t MVC an OOP pattern? Wasn’t React + Flux supposed to offer a functional paradigm? Isn’t Om, David Nolen’s ClojureScript wrapper of React, supposed to show that even more?

Well, here we have to define OOP. Smash Company recently posted an article about OOP that tries to deconstruct the definition and shows that OOP is a term that can mean many different things. I’m not trying to be pedantic, but I also know we will not be able to move forward without a clear definition. For the purposes of this post, we will adopt Alan Kay’s definition:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP.

If we focus on OOP as a pattern focused on components communicating via message passing and allow that MVC is an OOP pattern, then indeed, Reflux and MVI are both really just slight variations of MVC. In particular, the use of RxJS in the MVI approach makes this most clear.

Cool. So roughly 30 years after MVC was a good idea for building UIs, we find we agree. This reminds me of Bret Victor’s “Future of Programming” talk:

Is that it, then? Pick a “real” MVC framework or set of libraries and rewrite everything? If you want a “real” MVC framework, do you need to pick one of the above? What about Peter’s Maria, which resulted from his work on trying to uncover the “real” MVC in JavaScript?

First of all, you are asking two different things. AngularJS and Ember both offer models that can fit this approach okay, and both can work with React (last I checked, though I’ve never used Ember and am not certain as to this claim). Alas, it’s just not that simple.

Components

I neglected to mention that while looking through all these options, I ran into a little problem: most approaches assert that some specific component library is the “right” one to use. In particular, the virtual DOM approaches appear to be popular. However, where does that leave Web Components, component toolkits like Kendo UI, or DOM manipulation libraries like D3.js? How can you mix these into your virtual DOM library? For that matter, is a virtual DOM really necessary? I found Twitter’s Flight after beginning to prototype a similar idea and then finding a link to Flight in an article about CSP in JavaScript.

Right. Well, that certainly complicates things. Must you choose? What if you find some components in various libraries that would really work well for you? Must you really give up the ones not in your selected library? While you might appreciate using a consistent library or approach, I would argue you do not have to give up this flexibility.

OOP Revisited

So many people think OOP is directly at odds with FP. This is simply false. F#’s MailboxProcessor is an example of an agent, or actor-like, construct that maintains its own internal state and responds to messages. It may send its own messages or emit events to allow others to respond to its own processing. Doesn’t that sound familiar? If not, scroll back up to Alan Kay’s description of OOP.

In short, OOP is a strategy for designing in the large. This works exceedingly well with FP in the middle / small. Further, this sort of encapsulation means that you can create View abstractions around any and all of the above component libraries without worrying about them working directly with one another. Want Kendo UI, React, and Flight components to render side by side? No problem. You merely need a common abstraction or protocol through which they can communicate back to a common dispatcher and model. RxJS, as used in the MVI example above, is a good example of a library that may be useful. You can also use Maria or a handful of other libraries.

Fortunately, I’m not the only one thinking about things this way, at least in the sense of framework lock-in versus libraries. Andy Walpole just posted his thoughts in 2015: The End of the Monolithic JavaScript Framework. He does a great job showing the rise and fall in appreciation for monolithic frameworks. Chris Love has long been advocating for micro-libraries over frameworks. These don’t progress necessarily in the direction of MVC, and I don’t think I’ve yet covered why MVC could really be beneficial….

Distributed, Reactive MVC

If I recall correctly, Peter notes that the model is not the thing retrieved from a server request. I agree with the literal meaning of this statement, though I think he probably meant a bit more. (Apologies if I interpreted your meaning incorrectly, Peter.) Until I started writing this article, I was in full agreement with Peter’s assertion. You see, in classic, Smalltalk MVC, you had only a client. Actually, that’s not quite right. You had a world, an environment. The whole thing is available to you interactively. In such a programming environment, anything can be a Model, and if you read Peter’s article linked above, you would have caught that this was baked into Smalltalk intentionally. It’s reasonable to conclude then that the Model was the encapsulation of the domain.

We’re not talking about Smalltalk anymore, but the world of browser-based applications. Very little data is available within a browser-based application unless all the data is passed along with the markup. I’ve built apps that way in the past, and I bet you have done so, as well. However, we have learned new tricks that allow us to lazily retrieve data when and as necessary using tools like XMLHttpRequest. We have introduced distribution.

Distribution

If you watched Bret Victor’s video, you may remember seeing mention of the Actor model. When you think of the Actor model, what’s the first programming language you think of? I hope you said Erlang, mostly because of its history. I cannot remember where I first heard the story, but Joe Armstrong said that they created Erlang based on the ideas of Smalltalk while waiting on their first Smalltalk machine to arrive. In the end, they liked what they had built in the interim and never used the Smalltalk machine. (If anyone can find a reference to this, I’ll add it here.)

Here we can make a connection between Erlang and Smalltalk, between the Actor model and OOP. We can therefore confidently assert that OOP can involve distribution in its model (again following the definition from Kay above). Since MVC is an OOP pattern, we can further assert that MVC allows for distribution.

This raises a new question: even if all the players in MVC can be distributed, which should be distributed? This is a tough one. Let’s think together about how we build UIs. Using the desktop metaphor I raised in my previous post, we see that we could place multiple Views side-by-side within a single window. Following the Windows Store example, we could make the case for each View running in its own window. Also, depending on your definition of View, you may define something as small as a TextBox as a View, as it certainly qualifies as a component. You may therefore have any number of combinations. In most scenarios, though, I think we can safely assume that these will always exist on the client.

Let’s move on to Controllers. We could probably put these anywhere, but if we want to stick with a minimal definition like that used in the MVI pattern described in the Futurice article, I would argue that Controllers would best live close to their observed Views. You can certainly publish raw UI events across a network connection to be translated elsewhere, but this will mean you are primarily using RPC and may have to pass a lot of UI related context along with the event. I do like the idea of Controller as Intent, and I don’t like RPC much (more on this in just a bit), so I would argue the Controller / Intent also fits best in the client side. (Note: if you are building networked, client-side apps over a transport protocol, my argument falls flat, and I think you have more options as to where you might run this piece of the pattern.)

So far, I’ve stuck with my statement above and followed along quite nicely (I think) with Peter’s argument about MVC being a client-side pattern. However, we now need to discuss Models. Following the MVI terminology, Models receive Intent do some work and publish their revised state. I think we need some examples to understand distribution of Models.

Most single-player games can keep Model state quite close to its respective View and Controller. The state is most likely coordinated with a more global app state, as well (similar to the $scope hierarchy in Angular, actually.) However, once you start getting into distributed, multi-player games, you begin to see patterns like Flux (compared with Doom 3 in the linked video).

React Flux

What I find interesting is that in the case of Flux, the Intent (or Action in Flux / Reflux terms) communicates with the distributed part of the program. The Model (or Store in Flux / Reflux) remains a purely client-side concern. I won’t say this is wrong; I just wonder if this is really the right idea.

A few months ago, I was trying to visually conceptualize a similar idea. My original drawing had different terms related to my company’s product, but the general idea reduces nicely to a distributed, reactive form of the MVI variant of MVC:

I think either of the above are relatively good approaches. I’m partial to my drawing, but I certainly don’t think either are wrong. Nevertheless, I would like to dive a bit deeper into the Model and see where that leads.

In Search of the Model

What is the Model, really? I don’t know that I’ve ever seen a really clear explanation. The early MVC Models were simple, UI related concepts, but we seem to have grown the complexity of our apps far beyond that level of simplicity. The DDD and CQRS architectures provide some interesting ideas for defining a Model. Do these correlate with the Model in MVC? I don’t know for sure. In any case, you won’t typically represent either of these directly over HTTP.

Constraining this back to the topic of web-based applications. Web applications run over HTTP by definition. Anyone familiar with the HTTP 0.9 definition? What magic words do you happen to see there?

HTTP is a protocol with the lightness and speed necessary for a distributed collaborative hypermedia information system. It is a generic stateless object-oriented protocol, which may be used for many similar tasks such as name servers, and distributed object-oriented systems, by extending the commands, or “methods”, used.

Well, how about that? Maybe we are onto something! The only problem is that, in spite of the numerous clones of simple web API libraries, HTTP is quite a complex beast. Have you seen the state machine model?

ForGET HTTP State Machine Diagram for HTTP

Sure, you can avoid this diagram and roll your own way, but you lose a lot of the benefits of a standard protocol along the way, including a lot of the options available to understand what to do if something changes unexpectedly.

Most importantly, though, the diagram emphasizes the importance of leveraging HTTP resources as the Model for your application. Fortunately, tools like web machine and, for .NET, Freya exist to ease the challenges of trying to build the model yourself for each application. (I’ll be posting more on Freya later, but if you are interested in a sample, you can find the TodoBackend implementation on GitHub.) Even better, web machine correctly models REST, putting to … rest — excuse the pun — all the arguments and letting you focus on following the protocol. If you want to learn more, I recommend Sean Cribbskeynote from RestFest:

As I noted above, I plan to delve deeper into this specific concept further in the near future, so I’ll leave it for now.

Conclusion

I set out to show that MVC, the “real” MVC is in fact a pattern to which a lot of libraries and people are converging, whether they realize it or not. I think I’ve shown that, as well as that by adopting a more general pattern approach, you can leverage many of these component libraries’ styles in the same application, side-by-side. I’m curious to know your thoughts and whether anyone else has or is trying something similar. What have you found? Are you finding that such an approach works well?

I also set out to show that MVC can include an aspect of distribution. I think I highlighted this, as well, primarily in showing some of the original design goals of HTTP and aspects of OOP, and therefore MVC, that enable distribution. I don’t think I have a firm handle on exactly how to make this work, but I’m actively pursuing several aspects of distribution, both in terms of Model proxies in the client and building a web machine port for F# in Freya. What do you think? Is the Model proxy a good idea? Again, has anyone tried this approach and found it successful? Do you prefer the approach taken by Flux instead?

Please join the conversation! I’m very curious to know others’ opinions, including yours!

New Names for Old Things

[This is the third in a series started long ago on the use of MVC for building web “applications”.]

I’m glad I’m only getting back to this series now. I’ve had an opportunity to build many more web applications and have a much better appreciation for the poor terminology used to define web applications. For starters, this MV? business silly. We’ll get to that.

I know I’m a bit of an extremist in some things. Specifically, I like things to mean what they mean. When we abuse terms, we don’t communicate well. REST. There, I said it. I feel better. Stop using the term. Most people have a wrong idea of what it means b/c of all the silliness that has been done in its name. I don’t claim to know exactly myself. I don’t think it’s possible to rescue the term from the abuses heaped upon it. There, you see? I’m an extremist.

Now that we’ve covered that, on to MVC. I’m not sure who decided this was an accurate description for what happens on the server-side of the web, but it’s just flat wrong. As noted previously, HTTP uses a functional interface. It’s an IO-bound Request -> Response function. Can you use patterns on either side to help maintainability? Certainly! Just don’t confuse things. Let’s start with Views.

Views

What is a view?

The [view or viewport] is responsible for mapping graphics onto a device.
A viewport typically has a one to one correspondence with a display surface
and knows how to render to it. A viewport attaches to a model and renders
its contents to the display surface. In addition, when the model changes,
the viewport automatically redraws the affected part of the image to reflect
those changes. […] there can be multiple viewports onto the same model and
each of these viewports can render the contents of the model to a different
display surface.

If a view was merely a serialization of a model, this would make sense for building web applications. Unfortunately, there’s a problem. The definition suggests that the view automatically updates whenever the model changes. How do you do that with HTTP? HTTP doesn’t define any mechanism for hooking up observation of a server model. Before you say JavaScript, consider first the current use of View, or even UI. People commonly mean HTML. HTML is not a UI. HTML is a serialization format. The client (normally a browser) must interpret that HTML. Many of you will remember when that wasn’t so standard.

Can we achieve MVC today? Possibly. You might be able to leverage web sockets to reach across a client/server architecture such as that presented by HTTP. However, you are more likely to find that “MVC” on the server is just limiting. You are typically better off building a sort of restricted data access service, a.k.a Web API (subtle hint). There’s really no point in trying to enrich a serialization format to make it work more like true MVC across the client and server.

Controllers

This is no different than routing. Instead of calling your Router a Controller, you split them up. However, most frameworks really just use the router as a top level dispatcher and the controller as a lower-level dispatcher. Otherwise, I’d say web frameworks stay a lot closer to the original meaning than a lot of the other MV? patterns. (Hence the ?, of course.)

Models

This really is the crux. HTML is a model. I noted this last time. It’s just a serialization of data you want displayed. It happens to be a lot richer, but it’s still just a data model. HTML is a great way to bootstrap an application that otherwise uses JavaScript as a model serialization format. If you want to disagree, ask why HTML5 removes the presentation elements. Why has layout and style moved to CSS? CSS and the browser define the actual rendering. In a no-script web application, you don’t have to build a view. You get it for free.

Conclusion

So what? Am I just ranting that I don’t like how people abuse terms? Possibly. However, I think this goes deeper. When you allow the slippery slope, you get caught on it, as well. It’s inevitable. The bigger, lurking danger is that we start to confuse useful patterns and use them in the wrong places. Many people use MVC frameworks today to build web APIs. However, that’s not MVC. So if you then switch to a desktop app to write MVC applications, you are either confused or delighted to find that it’s so much richer.

I don’t know what I would call what we build for the web; I know I wouldn’t call it MVC. In my experiments with Frank, I’ve found that writing simple functions and nesting them with rules makes a very easy mechanism for building web APIs. I think that would essentially just be a Command pattern. Simple, elegant, and very easy to understand. YMMV.

A New Web for .NET: FubuMVC and Chad’s Response to AR Considered Harmful

I caught a few interesting posts this week that reminded me of an unfinished series on .NET web frameworks I started in 2009. The series, as it was initially planned, ties in very well with a recent post from Chad Myers, who responded to another post claiming the ActiveRecord (and Rails) Considered Harmful.

Before I go any further, I want to make very clear that I’m a fan of Rails and think that it is an incredibly useful framework for building certain applications. I think the same is true of ASP.NET MVC. I’ve used and use both. However, I don’t think that means these are the best approach for tackling HTTP.

Chad’s post was very good. I agree with almost all of his points. In particular, I think he hit several very important points, the biggest of which was his emphatic quote:

INHERITANCE IS FAIL FOR MOST DESIGNS, BUT NEVER MORE SO THAN IN WEB/MVC FRAMEWORKS!

Then from his list of criteria for a “perfect” web framework:

  • Completely compositional: 100% agree
  • [Resource]-based: I take a slightly different direction here. We talk about “models”, but if you are really thinking about HTTP, you should be thinking in terms of resources. They are similar in many ways, notably in the sorts of “behaviors” (in FubuMVC terms) that should be composed with the “model.” Honestly, it’s the “model” term itself that seems totally overloaded or at least at the wrong layer when talking about a framework. If you have a model, you’re probably really dealing with something more like DDD than the HTTP application layer.
  • Not have any notion of controllers: Agree. In MVC-style frameworks, they are sort of necessary, but if you break away from MVC, you’ll find there are better alternatives.
  • Action-based: I’m all about using functions, or delegates, as 'Request -> 'Response handlers. I also agree that these should generally be kept simple, relying on compositional helpers, middlewares, or whatever you want to call them to perform model-binding and response generation. Granted, this is slightly different than what Chad is talking about, and I’ll cover my thoughts on this in more detail below.
  • Minimized code-in-view: templates are helpful, but the ability to add a lot of logic is just asking for trouble. I really like the tags-as-code approach taken by WebSharper and Wing Beats.
  • Independent of other frameworks: Definitely limit other dependencies and play nice with others.
  • Testing as a first-class citizen: At least allow whatever the consumer writes to easily write real unit tests. Generally, the only reason you can’t do this is related to hosting, so make sure the hosting model is not necessary to test the application.

Okay, so I obviously skipped some items. I don’t think the other items are bad; I just don’t think they are necessary for a “perfect” web framework.

  • Total adherence to principles: This sounds really good. I don’t disagree, really, but exactly which principles? Principles sometimes change. Some make sense in one approach to software development and are sort of non-issues in others. Look at the description of SOLID and its relevance to F#. You’ll note that many of the principles are sort of non-issues.
  • Statically typed: I don’t really see this as a requirement. HTTP is inherently dynamic. You could build a useful, fairly complex HTTP application using only dictionaries. Reliance upon type serialization is misguided. How do you generate accurate Atom or HTML from a static type? You don’t. You need a template or some other custom output. At the same time, I have grown to like static type-checking, espeically in F#, and F# 3.0’s Type Providers prove you can do a lot, even type check regular expressions. I just don’t see this as a strict requirement.
  • Based on IoC: I love IoC in C# applications. I can’t imagine life without it. However, I’ve found that I don’t even think about IoC when writing F# applications. It’s just not a concern. Higher-order functions, computation expressions, and other functional-style approaches generally render IoC a non-issue. So again, I don’t really see this as a requirement but a case of “use the right tool for the job.”
  • Mostly model-based conventional routing: This is a totally fine solution. I take issue with having any single prescription for routing. There are so many ways to handle this, and in the end it doesn’t matter. If you stick to a resource-oriented approach, which perhaps is the goal Chad is getting at, then your routing should be pretty straightforward and simple. One thing many routers miss is the connection between different methods assigned to a single uri. So far as I know, OpenRasta and Web Api are the only frameworks that return the appropriate HTTP status codes for missing methods on an uri or unmatched Accept header, among other things. FubuMVC may allow this through a convention.
  • One Model In, One Model Out: When using MVC, I generally like this approach. However, I again don’t see this as a requirement. I’m not convinced a model is always necessary. Again, HTTP is quite dynamic, and it’s sometimes easier to work directly with a request or pull out several different “objects” from a request to help generate a response. Though perhaps 'Request and 'Response are models and the point is moot. 🙂

Now for the biggest divergence: I generally prefer to be explicit rather than lean on conventions. In C#, I typically go for conventions because of the amount of noise required by the C# syntax. With F#, I’m able to be explicit without suffering syntax noise overload. The same is true for many dyanmic languages like Ruby and Python. So I disagree with both the Conventional top-to-bottom and Zero touch points. Again, I’m not fully opposed, but I definitely don’t see these as requirements at the framework level. Sure, include it as an option, especially if, as in FubuMVC, you can redefine the conventions to suit your needs. This could just mean use the right tool for the job, or it could mean you should take a simpler approach and build your own conventions as wrapper functions.

If you think this sounds like a prescription to write a lot more code, I’ll show a comparison:

Two extra lines (in this instance) and it’s likely with a more complex example you wouldn’t see much of a difference in terms of line count. I doubt this is true with C#, so don’t take this as a statement that this is the “one, true way.” I like conventions when using C#, just as I like IoC in C#.

In any case, definitely check out FubuMVC as an alternative to MVC. There’s a lot to like, and the FubuMVC team has done an incredible job building a terrific platform. I’ll try to highlight a few others in the upcoming weeks, but while you’re looking at Fubu, also checkout OpenRasta and ServiceStack.

A New Web for .NET: FubuMVC and Chad's Response to AR Considered Harmful

I caught a few interesting posts this week that reminded me of an unfinished series on .NET web frameworks I started in 2009. The series, as it was initially planned, ties in very well with a recent post from Chad Myers, who responded to another post claiming the ActiveRecord (and Rails) Considered Harmful.

Before I go any further, I want to make very clear that I’m a fan of Rails and think that it is an incredibly useful framework for building certain applications. I think the same is true of ASP.NET MVC. I’ve used and use both. However, I don’t think that means these are the best approach for tackling HTTP.

Chad’s post was very good. I agree with almost all of his points. In particular, I think he hit several very important points, the biggest of which was his emphatic quote:

INHERITANCE IS FAIL FOR MOST DESIGNS, BUT NEVER MORE SO THAN IN WEB/MVC FRAMEWORKS!

Then from his list of criteria for a “perfect” web framework:

  • Completely compositional: 100% agree
  • [Resource]-based: I take a slightly different direction here. We talk about “models”, but if you are really thinking about HTTP, you should be thinking in terms of resources. They are similar in many ways, notably in the sorts of “behaviors” (in FubuMVC terms) that should be composed with the “model.” Honestly, it’s the “model” term itself that seems totally overloaded or at least at the wrong layer when talking about a framework. If you have a model, you’re probably really dealing with something more like DDD than the HTTP application layer.
  • Not have any notion of controllers: Agree. In MVC-style frameworks, they are sort of necessary, but if you break away from MVC, you’ll find there are better alternatives.
  • Action-based: I’m all about using functions, or delegates, as 'Request -> 'Response handlers. I also agree that these should generally be kept simple, relying on compositional helpers, middlewares, or whatever you want to call them to perform model-binding and response generation. Granted, this is slightly different than what Chad is talking about, and I’ll cover my thoughts on this in more detail below.
  • Minimized code-in-view: templates are helpful, but the ability to add a lot of logic is just asking for trouble. I really like the tags-as-code approach taken by WebSharper and Wing Beats.
  • Independent of other frameworks: Definitely limit other dependencies and play nice with others.
  • Testing as a first-class citizen: At least allow whatever the consumer writes to easily write real unit tests. Generally, the only reason you can’t do this is related to hosting, so make sure the hosting model is not necessary to test the application.

Okay, so I obviously skipped some items. I don’t think the other items are bad; I just don’t think they are necessary for a “perfect” web framework.

  • Total adherence to principles: This sounds really good. I don’t disagree, really, but exactly which principles? Principles sometimes change. Some make sense in one approach to software development and are sort of non-issues in others. Look at the description of SOLID and its relevance to F#. You’ll note that many of the principles are sort of non-issues.
  • Statically typed: I don’t really see this as a requirement. HTTP is inherently dynamic. You could build a useful, fairly complex HTTP application using only dictionaries. Reliance upon type serialization is misguided. How do you generate accurate Atom or HTML from a static type? You don’t. You need a template or some other custom output. At the same time, I have grown to like static type-checking, espeically in F#, and F# 3.0’s Type Providers prove you can do a lot, even type check regular expressions. I just don’t see this as a strict requirement.
  • Based on IoC: I love IoC in C# applications. I can’t imagine life without it. However, I’ve found that I don’t even think about IoC when writing F# applications. It’s just not a concern. Higher-order functions, computation expressions, and other functional-style approaches generally render IoC a non-issue. So again, I don’t really see this as a requirement but a case of “use the right tool for the job.”
  • Mostly model-based conventional routing: This is a totally fine solution. I take issue with having any single prescription for routing. There are so many ways to handle this, and in the end it doesn’t matter. If you stick to a resource-oriented approach, which perhaps is the goal Chad is getting at, then your routing should be pretty straightforward and simple. One thing many routers miss is the connection between different methods assigned to a single uri. So far as I know, OpenRasta and Web Api are the only frameworks that return the appropriate HTTP status codes for missing methods on an uri or unmatched Accept header, among other things. FubuMVC may allow this through a convention.
  • One Model In, One Model Out: When using MVC, I generally like this approach. However, I again don’t see this as a requirement. I’m not convinced a model is always necessary. Again, HTTP is quite dynamic, and it’s sometimes easier to work directly with a request or pull out several different “objects” from a request to help generate a response. Though perhaps 'Request and 'Response are models and the point is moot. 🙂

Now for the biggest divergence: I generally prefer to be explicit rather than lean on conventions. In C#, I typically go for conventions because of the amount of noise required by the C# syntax. With F#, I’m able to be explicit without suffering syntax noise overload. The same is true for many dyanmic languages like Ruby and Python. So I disagree with both the Conventional top-to-bottom and Zero touch points. Again, I’m not fully opposed, but I definitely don’t see these as requirements at the framework level. Sure, include it as an option, especially if, as in FubuMVC, you can redefine the conventions to suit your needs. This could just mean use the right tool for the job, or it could mean you should take a simpler approach and build your own conventions as wrapper functions.

If you think this sounds like a prescription to write a lot more code, I’ll show a comparison:

Two extra lines (in this instance) and it’s likely with a more complex example you wouldn’t see much of a difference in terms of line count. I doubt this is true with C#, so don’t take this as a statement that this is the “one, true way.” I like conventions when using C#, just as I like IoC in C#.

In any case, definitely check out FubuMVC as an alternative to MVC. There’s a lot to like, and the FubuMVC team has done an incredible job building a terrific platform. I’ll try to highlight a few others in the upcoming weeks, but while you’re looking at Fubu, also checkout OpenRasta and ServiceStack.

ViewModel Futures

Glenn Block asked two questions on Twitter tonight that were too good to pass up. First, do you want better tooling, more testable data binding, or a ViewModel base class? I agree with whoever said patterns exist to make up for faults in a language; however, in this case, I think I would choose enhancements to data binding. It’s a little too magical, imho.

I would like to see a ViewModel base eventually, though, as that would be one less thing to wire up myself, and it hopefully silence all the people complaining about the lack of a model in MVC. (Yes, I am thinking the backend models should be sharable among WPF, Silverlight, and MVC.)

Glenn’s second question related to tv target audience. I am always a fan of simple explocicity, to borrow a word from JB. I think that’s what the experts use. Also, I don’t know many who want to me mediocre some day, so going for the best and letting it trickle down is a great idea.

Just my $.02.