2011 Conceptual Web Framework Utopia — Part 1, “Architecture”

2011 Conceptual Web Framework Utopia — Part 1, “Architecture”

Bad experiences scar us — forcing us to learn for our own survival. This evolutionary theory can also be applied to software. If you don’t learn from your mistakes, you’ll soon be on this guy’s plate:

So when creating web apps, what have my survival instincts really taught me?

They’ve taught me that almost nothing applies universally. Since I generally create larger-scale web apps, this article applies primarily to that context. Even in this context, though, trade-off benefits will vary for specific circumstances.

They’ve also taught me to isolate the domain, keep the web layer thin and listen to the wise words of people of like Uncle Bob, Udi Dahan & Eric Evans. They’ve even taught me (via Udi Dahan) to “justify why the simplest possible thing isn’t enough” — so expect lots of that too.

In this series of blog posts — reflecting my current thinking — I will be showing:

  1. The “Architecture” (clarify the quotes the later)

  2. My unit testing strategy

  3. A few other preferred patternsWhat Does it Look Like?

First, when I talk about architecture, I apply it generally and mean any component of the system as a whole — not just the domain. This contradicts Uncle Bob and may be wrong, but I couldn’t think of another phrase that would be understood that encompassed domain and delivery mechanism(s).One Model In One Model Out & Endpoint-specific Models

A recent addition I picked up is the OMIOMO (one model in one model out) convention from fubumvc — each action receives a request or input model and returns a view model (or some other model).

By making these models specific to each action, they are very simple data structures — keeping cognitive load to a minimum. It also saves you from having shared view models that introduce bugs when they change for one view and cause another to break.

Endpoint-specific models facilitate the Endpoint Testing Pattern — discussed in part 2.Endpoints Talk to Domain Services in DTO Language

Transfer of information between endpoints/controllers and domain services is through simple DTO data structures.

Here’s an example:

Endpoint using a query service

public CreateBookViewModel Get(CreateBookLinkModel model)

{

IEnumerable genres = genreRetriever.GetAllOrderedByName();

return new CreateBookViewModel(genres);

}

Implementation of query service

public IEnumerable<GenreDto> GetAllOrderedByName()
{
var genres = session
.Query<Genre>()
.OrderBy(g => g.Name);
return genres.Select(g => new GenreDto {Id = g.Id, Name = g.Name});
}
public bool CanFindGenreWith(string id)
{
return session.Query<Genre>().Count(g => g.Id == id) > 0;
}
```Why Bother with DTOs?

Critically, the use of DTOs protects the domain *and *your application — the contract between your application and domain is a lightweight data structure. With this loose contract, the domain model is free to evolve — and when you’re applying DDD, with the need to refactor often and sometimes aggressively — your domain model has no outside concerns to worry about.

When you do apply domain refactorings, as long as you still meet the contract — the DTO — your application remains unaffected.

I won’t explain the **business value **of DDD.Why Separate Services to Query and Command?

A philosophy in CQRS is to separate reads and writes for architectural flexibility. At the heart it is a simple pattern. Generally it appears to be used when reads and writes have a separate data model — but in my case, the domain data model is hidden — so it could be the same or different — we have the flexibility. But what about the cost……Isn’t Hiding Your Data Access Bad?

In [some](http://ayende.com/blog/4786/the-wages-of-sin-over-architecture-in-the-real-world) cases — yes. But for my example, I’d argue — no….domain isolation is worth it. It is a very thin layer, two mouse clicks away and one interface agreement. Data access needs to know domain entities and the underlying data model — to gain the benefits of DDD we don’t want to expose that to the application layers.

I think a thin layer of domain service implementations (not interfaces) that take a dependency on the data access is ok. Some people put them in a separate project, some people chuck it all in the controller — I like this middle ground.

Data access is a tricky, context-specific beast that this is probably the least prescriptive of my ideals.

Using this pattern and RavenDb also gives rise to a good strategy for comprehensive testing of data access — you’ll see that in part 2 as well.An Example From the Wild

You start out with a synchronous N-Tier application, but your domain model rapidly evolves — with the DTOs being passed between boundaries this is no more difficult than necessary because the domain is isolated.

Suddenly you have multiple bounded contexts, sharing aspects of what once was a single domain entity — so you want to switch to an asynchronous messaging based architecture. As long as you have a separate service for queries and commands, with your data model hidden, you can focus totally on the domain and its contract to the outside world — DTOs.

For those thinking this doesn’t happen — it is the exact situation I am in with the contract I am working on, and appears not uncommon from what I hear elsewhere. If the application followed these principles, changes would be isolated to the domain and we’d only have to worry about meeting service interface criteria — unfortunately there are swathes of inter-twined spaghetti code all through the application *and* domain that are affected — **there’s your business value, son**.So…..

Cowboys have their opinion, those in ivory towers voice quite another. But experience and practice are crucial in finding out what really works and the contexts in which the arguments put forward by each are favourable.

Reflecting on experiences, using personal projects to test assumptions and try new ideas is a great way to get closer to that firm-footing of reality. If you keep doing the same — you’ll keep getting the same. I was pretty bored of those domain entity model binding issues and domain refactorings causing crippling breakages in my web layer — so here’s a small conceptual step, less destined for failure.

Also when you write posts like these, you force yourself to double-check blog posts and podcasts — just to make sure you correctly understood the topic. This reinforces what you’ve learnt, also saving you from any false assumptions you may be carrying on your sleeve.

Tune in for part 2.Related Shizz

Martin Fowler, CQRS — [http://martinfowler.com/bliki/CQRS.html](http://martinfowler.com/bliki/CQRS.html)

Uncle Bob, Web Architecture — [http://www.cleancoders.com/codecast/clean-code-episode-7/show](http://www.cleancoders.com/codecast/clean-code-episode-7/show) AND [http://skillsmatter.com/podcast/design-architecture/uncle-bob-web-architecture](http://skillsmatter.com/podcast/design-architecture/uncle-bob-web-architecture)

Udi Dahan talk on SOA — [http://skillsmatter.com/podcast/open-source-dot-net/qa-with-udi-dahan](http://skillsmatter.com/podcast/open-source-dot-net/qa-with-udi-dahan)