This article appears to be from 2004, but I just stumbled upon it today. It seems to give a decent explanation about why there’s no one true MVC pattern in web applications.

Here are some excerpt snippets:

In a desktop application, the Model, View, and Controller run on the machine that the user interacts with. … In a web application, the server software runs on a server, and the user interacts with browser software running on a client. … Client-server programming is difficult because the program is distributed across more than one network node. Some code has to run on the client to interact with the user. Other code has to run on the server to interact with the data store. … View updates in Server-Side MVC are more coarse-grained than they are in a desktop application. A Server-Side MVC application can’t generally update just part of a view (or an interior node in a view hierarchy); it has to create an entirely new view and replace the old view by the new one, even when the new view is almost identical to the old one. … User events in Server-Side MVC are more coarse-grained than they are in a desktop application. Multiple client-side user events, such as a series of clicks and keystrokes, are aggregated into a single HTTP request that summarizes their effect.

It’s fair to say that none of the server-side frameworks are true MVC. (We might call them a variant of MVC or inspired by MVC.) Probably no server-side web application can ever be true MVC, because MVC isn’t applicable to client-server programming.

Whenever I’ve read any article on MVC, I’ve never read any that clearly defines what goes in the model and what goes into the controller. Any of the articles that mention “business logic” don’t define what they mean by “business logic” and whether “business logic” can be broken down into smaller parts, and which of them parts would go into the model and which would go into the controller.

I find I mostly always put my database logic in the model and then return that data and manipulate it using the controller. But I know others who use the model to arrange the data as they get it too.

The business logic… Imagine for a moment that there’s no user input and no presentation output. Just a library of code that manages the behavior a specific set of data. That library is your business logic. Maybe we’ll wrap it in a GUI or a CLI or a web app, but the business logic gets to be indifferent to those considerations. So if you’re trying to decide whether some bit of code belongs in the business logic or elsewhere, then try to imagine that you’re writing a CLI instead of a web app. Would the code you’re writing still be applicable? If so, then it’s part of the business logic.

The rest depends on whether we’re talking about traditional desktop MVC or server-side web MVC.

The model:
In traditional desktop MVC, the model is your data, plus the business logic that manages that data, plus one or two additional responsibilities. One of those additional responsibilities is to allow other objects to attach event listeners to the model, and when the model’s data changes, it notifies those listeners. The view in particular attaches listeners so that it can take action when the data being presented has changed. In server-side MVC, however, these additional responsibilities are redundant. The view will never need to update itself, and the model won’t need to notify anyone. So in server-side MVC, the model is just your data and the business logic that manages that data.

In traditional desktop MVC, every window, every input box, every button is a separate view, and each of those views has its own controller. The job of each of those controllers is to interpret mouse/keyboard/whatever inputs from the user. So, for example, the input box’s controller might interpret a click as a command for the view to focus that element. Or the button’s controller might interpret a click as a command for the model to save data. In server-side MVC, however, the controller’s job is vastly different. There won’t be any mouse or keyboard inputs. There’s just the HTTP request. And the controller’s job is to convert that request into an HTTP response.

In server-side MVC, probably one of the spots where the responsibilities of the controller and of the business logic blur together is with validation. The form data comes to us as an HTTP request, so that means it’s the controller’s responsibility to validate that data, right? But we would need to do validation even if we were building a CLI app, so that means it’s the business logic’s responsibility, right? To get this correct, we need to carefully bridge the two. The controller should use the HTTP form data to instantiate an entity object from the business logic’s library code, then the business logic’s library code would provide the means to validate that entity object. Then the controller can use the result of that validation when composing its response.