Architecting a MVC web application with Knockout

Standard

One of the most recurring questions I see on StackOverflow (for example here) and the likes is about best practices for architecting MVC web applications and about integration with “this” or “that” javascript framework without messing up the whole design.
So I decided to share my thoughts on this, because I know how confusing and hard it can be, especially for beginners, to put all the pieces of the puzzle together.
I chose to take Knockout as an example because I like its MVVM approach and the learning curve is not so steep.
Finally, as always, the foundations of this article lie in my own personal experience mixed with all the books and articles I read, therefore this article might be quite simplicistic or naive to someone with much more experience than me, or maybe someone else will just disagree.
In every case, feel free to express what you think!

MVC

Asp.Net MVC and similar frameworks are cool and powerful, they often offer nice and easy predefined project structures and convetions, so why bothering making things more complex?
Well, conventions are surely great, but when it comes to projects that have more than a few classes, views or controllers, or projects that relies on other teams work, or simply projects that want to adopt a more structured architecture, the basic project template just isn’t flexible enough.
MVC is an architectural pattern about the Presentation layer and how it connects to the Application layer, but what about the rest of the application? How do we further logically divide the software? And how do we connect these logical parts?

Architecture

The standard solution to the questions mentioned above is to use a layered architecture, few and fairly standard in their definition. To enforce well known principles like high coesion, do not repeat yourself etc, each of these layer specialises in a particular aspect of the software.
Each layer speaks a language, usually (with some exceptions, as we will see later) the language of the domain the software is related to, and uses layers beneath to fulfill some task.
The general diagram for the architecture I will talk about is the following:

Architecture

Architecture

The focus of this article is on the Presentation Layer, its integration with Knockout and the connection between the Presentation and the Application layer.

View Model

By definition, the M in MVC stands for Model, but what is exactly the Model we are talking about? The Asp.Net MVC doesn’t constraint the developer to define what M stands for, it could be a Domain Model object (using any kind of pattern, Active-Record, Entity, Value etc…) or it could be something else.
In the solution proposed in this article, the M stands for View Model.
This View Model is not to be confused with the Domain Model, that is the core language of the real world problem our application is trying to solve.
It is instead the language of the Presentation layer, used by Views (our HTML pages) and the Controllers (can be code-behind or Controller objects).
The MVC default project structure that we find in Visual Studio, for example, with its “Model” folder can easily mislead us on this, leading us to mix both worlds not even being aware of that!

What a View Model is

A View Model object is crafter around a specific View and should contain only the elements the View needs to display and optionally validation rules.
Every View should be strongly typed to a View Model object, so that you don’t have to mess up with loose strings or similar, being able instead to work with the MVC scaffolding engine, strongly typed variables and all the HTML helpers while building up your View.
I think it is a good practice to name the View Model object after the View and the specific action, for instance EditCustomerViewModel or CreateCustomoreViewModel, so that it’s easy to do the association between the View and the View Model object.
View Model objects often aggregate Domain Model objects or viceversa may map to only a subset of a Domain model object’s properties, and they may also contain View specific validation rules (for example Asp.Net MVC 3 comes with lots of built-in Data Annotation attributes that we can use to decorate classes or properties to express requirements about fields, data format etc…).
Let’s take as an example a page where the user can Create a new customer: we won’t display a field for customer ID whereas in the corresponding Edit page we may display it as a read only field.
This difference is well expressed using two distinct Views and two distinct View Models, each with different properties and attributes that adapt to the page.
It may seem like a lot of additional work to write two different Views and View Models, but it will pay you back in terms of ease of maintenance and clarity of intents when sharing the work with other people.
Furthermore by following this approach our Views contains no logic to handle different cases like “Edit” and “Create”, they just worry about data visualization like they should.

Views

Lots of javascript framework that help developers delivering a dynamic and interactive user experience are available these days, automating the task of writing repetitive javascript code to hook up DOM objects and events handlers, at the cost of the initial learning curve and the additional code to setup it.
I chose Knockout, which brings the MVVM pattern to the web, because the declarative bindings. are easy to understand and use, it’s easy to extend, it’s very well documentend, the website is full of useful examples and the additional amount of code to setup the framework is not too much.
Knockout requires the developer to write a javascript View Model (from now on referred as Knockout View Model) per each View we want to use it in and the declarative data bindings on each DOM element we want to observe. Once this is done, Knockout can keep track of the state of the controls displayed in the page. Whenever the user will change the state of whatever “observed” control in the page, the underlying Knockout View Model will automatically update itself.
This feature is killer for example if you’re writing a Single Page Application: one full load when the user requests the page for the first time, and every other interaction is an Ajax call where we already have the page state ready for use in javascript.
At this point you may ask: another view model? Didn’t we already have a Domain Model and a View Model?
Yes, that’s true, but every model has its own scope, and the Knockout View Model scope is to contain the presentation display logic and the state of the observed controls.
The View Model is used by the Controller Action that is responsible for loading the View the first time: it will databind the View to the View Model, so that the page is initialized quickly without the need to perform Ajax calls to load data from the server.
If the View is smartly initialised with data coming from the View Model, for example pre-ticked checkboxes, pre-filled textboxes , pre selected item in select list etc… our Knockout View Model won’t know about them unless we explicitely assign every initial values.
One way to do it is by Json encoding the bounded View Model and then assigning each pre-defined value to the Knockout View Model variable containing the observable value.
For example:

var boundedViewModel = @Html.Raw(Json.Encode(Model));
var viewModel = {
selectedCity: ko.observable(boundedViewModel.DefaultCity);
…
}

The Application Layer

Also known as middle tier, it works with Domain Model objects, the Repository and other Foundation services, to work out Presentation layer requests.
To be able to communicate, the Application and Presentation layer share the same language, the View Model objects.
If they were part of the Presentation layer, as suggested by the “Model” folder that we find in the default Asp.Net MVC project, the Application would need to have a reference to it to manipulate them, thus creating a circular reference!
To avoid such a problem we create a separate dll containing View Models, referenced by both the Presentation and the Application layer.
It is then the Application layer responsibility to translate from View Model to Domain Model objects and viceversa.
For this task it is possible and strongly suggested to use automated tools to do the mapping for us, such as AutoMapper for .Net (it is also available on NuGet).
By delegating this task to the Application, the Presentation layer is free from any mapping logic and from any reference that is not directly involved in its core business.

Closing thoughts

In this article we have seen a flexible solution to architect a MVC web application by
introducing a new object Model, the View Model, and its rules that together create an ad-hoc language for the Presentation layer that will help us in the task of building elegant front-ends and to an easier integration with javascript frameworks such as Knockout.

References

Lots of inspiration for this article comes from the following articles:

  1. http://msdn.microsoft.com/en-us/magazine/hh456393.aspx , where you’ll be able to find also more info on the Domain Model and the Repository layer.
  2. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
  3. http://www.methodsandtools.com/archive/archive.php?id=97

One thought on “Architecting a MVC web application with Knockout

  1. You truly constructed quite a few excellent stuff in your blog post,
    “Architecting a MVC web application with Knockout | thewayofcode”.

    I am going to remain heading back to your web-site
    before long. Thanks -Candra

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s