6

As a result of a previous post (Architecture: simple CQS) I've been thinking how I could build a simple system that is flexible enough to be extended later.

In other words: I don't see the need for a full-blown CQRS now, but I want it to be easy to evolve to it later, if needed.

So I was thinking to separate commanding from querying, but both based on the same database.

The query part would be easy: a WCF data service based on views to that it's easy to query for data. Nothing special there.

The command part is something more difficult, and here's an idea: commands are of course executed in an asynchronous way, so they don't return a result. But, my ASP.NET MVC site's controllers often need feedback from a command (for example if a registration of a member succeeded or not). So if the controller sends a command, it also generates a transaction ID (a guid) that is passed together with the command properties. The command service receives this command, puts it into a transactions table in the database with state 'processing', and is executed (using DDD principles). After execution, the transactions table is updated, so that state becomes 'completed' or 'failed', and other more detailed information like the primary key that was generated.

Meanwhile the site is using the QueryService to poll for the state of this transaction, until it receives 'completed' or 'failed', and then it can continue its work based on this result. If the transactions table is polled and the result was 'completed' or 'failed', the entry is deleted.

A side effect is that I don't need guid's as keys for my entities, which is a good thing for performance and size.

In most cases this polling mechanism is probably not needed, but is possible if needed. And the interfaces are designed with CQS in mind, so open for the future.

Do you think of any flaws in this approach? Other ideas or suggestions?

Thanks!

Lud

Community
  • 1
  • 1
L-Four
  • 13,345
  • 9
  • 65
  • 109
  • 1
    Why do you decouple your front end through a WCF data service? Is there a specific reason for this as I would keep my solution as simple as possible to start with. – thekip Aug 11 '11 at 19:31
  • 1
    +1 for not going WCF. Fowler's First Law of Distributed Object Design: Don't distribute your objects (from PoEAA) – Deleted Aug 11 '11 at 19:57
  • @thekip, Chris Smith andDavid Hoerster: I got the advice from someone: "For scalability, it helps to separate back-end code from front-end code. So if you put UI code in the MVC project and as much processing code as possible in one or more separate WCF and business logic projects, not only will your code be clearer but you will also be able to scale the layers/tiers independently of each other.". What do you think of this? – L-Four Aug 12 '11 at 07:35
  • Sounds like premature optimization to me. I don't know what you're working on but unless you expect 100+ concurrent users or really high volumes of traffic I wouldn't take this decision upfront. – thekip Aug 12 '11 at 13:15
  • @thekip: the site kan become very big... that's why I want to take a really good decision based on reason :) do you think that I should not use a service layer? – L-Four Aug 12 '11 at 14:00
  • Lud - I agree with the statement about separating back-end from UI code. Depending on how you deploy your solution, I'm not sure how much ind. layer scalability you can achieve. You'd have to have a pretty loosely coupled system, INHO, for this. I think separating the UI/biz/etc. layers helps with maintainability, testing and organization. I'd consider @thekip's suggestion that you don't want to optimize too early. I think you should have some basic layers created - but you can always refactor some of that logic out into separate projects and layers once you see how the project goes. – David Hoerster Aug 12 '11 at 14:02
  • @David: so you mean I should put the layers in place, using the interfaces as I would do it with WCF, but don't use WCF right now (refactor later if needed with little effort). I'll think about it, but I think it's good advice! Thanks! – L-Four Aug 13 '11 at 15:18
  • I wouldn't say don't go with WCF Data Services right now, as that may affect how you're querying for data on your client. I was suggesting that you may not want to break everything that you can into separate projects/layers right away. So keep the WCF data service, but may don't break the custom service method and interceptor implementation into a separate project. Keep the pieces kind of big to start in order to see what works - then refactor into smaller projects. Great questions on CQRS - keep 'em coming! – David Hoerster Aug 13 '11 at 16:17
  • 1
    Ok I understand 'Don't distribute your objects' concept. It basically means: don't create service unless you really need to, and in my case I don't think there is any reason. But, why should I then still use wcf data services? – L-Four Aug 14 '11 at 14:07

1 Answers1

5

I think you are very close to a full CQRS system with your approach.

I have a site that I used to do something similar to what you are describing. My site, braincredits.com, is architected using CQRS, and all commands are async in nature. So, as a result, when I create an entry, there is really no feedback to the user other than the command was successfully submitted for processing (not that it processed).

But I have a user score on the site (a count of their "credits") that should change as the user submits more items. But I don't want the user to keep hitting F5 to refresh the browser. So I am doing what you are proposing -- I have an AJAX call that fires off every second or two to see if the user's credit count has changed. If it has, the new amount is brought back and the UI is updated (with a little bit of animation to catch the user's attention -- but not too flashy).

What you're talking about is eventual consistency -- that the state of the application that the user is seeing will eventually be consistent with the system data (the system of record). That concept is pretty key to CQRS, and, in my opinion, makes a lot of sense. As soon as you retrieve data in a system (whether it's a CQRS-based one or not), the data is old. But if you assume that and assume that the client will eventually be consistent, then your approach makes sense and you can also design your UI to account for that AND take advantage of that.

As far as suggestions, I would watch how much polling you do and how much data you're sending up and back. Do go overboard with polling, which is sounds like you're not. But target what should be updated on a regular basis on your site and I think you'll be good.

The WCF Data Service layer for the query side is a good idea - just make sure it's only read-enabled (which I'm sure you've done).

Other than that, it sounds like you're off to a good start.

I hope this helps. Good luck!

David Hoerster
  • 28,421
  • 8
  • 67
  • 102