Put your controllers on a diet: POSTs and commands

Previous posts in this series:

In the last post, we looked at encapsulating the interesting part of GET actions (taking request parameters and building a model) into individual encapsulated query objects and handlers. Not surprisingly, we’ll be using similar techniques on our POST side to handle form POSTs and actually…doing something with those results.

There are a couple of things we need to deal with before we get to looking at going all the way to handlers. First, let’s review our POST action:

[HttpPost]
public ActionResult Edit(ConferenceEditModel form)
{
    if (!ModelState.IsValid)
    {
        return View(form);
    }

    var conf = _session.Get<Conference>(form.Id);

    conf.ChangeName(form.Name);

    foreach (var attendeeEditModel in form.Attendees)
    {
        var attendee = conf.GetAttendee(attendeeEditModel.Id);

        attendee.ChangeName(attendeeEditModel.FirstName, attendeeEditModel.LastName);
        attendee.Email = attendeeEditModel.Email;
    }

    return this.RedirectToAction(c => c.Index(null), "Default");
}

Ugh, what awful code! Well, not really. There’s nothing particularly smelly about this controller action in isolation. It’s got a few concerns going on:

  • Validation checking
  • Form handling
  • Success redirection

Again, nothing really pushing us to refactor this code. If I had many of these actions, I might be inclined not to copy that “ModelState.IsValid” check all over the place. There are other things I’d like to not copy around, things like:

  • Authorization
  • Logging
  • Auditing
  • Eventing (i.e., processing side-effects or ancillary actions)

The above controller action doesn’t look bad, but I often have to do activities across all my actions. So what are our options?

First, we might look at filters. Authorization is built in to MVC as a filter, so that knocks that off the list. What about the others? Logging, auditing, and ancillary actions? Those all work well when I have a fully-built model , and some knowledge of what activity is being performed. Those are the kinds of activities that benefit by flowing through a common pinch-point, and the UI layer just doesn’t have the right hooks for us.

But first, let’s get rid of that validation piece.

Client/server validation

I’ve never really been a fan of client-side validation. It works well for simple cases, but I never want to be in the spot of writing my validation rules twice. At most, I want to write them once and have them perhaps generated to client-side rules.

Luckily, a teammate already blogged on a fantastic approach where the general idea is to create an action filter that performs validation on the server side, and returns a JSON model (just ModelState as JSON) with the model properties and validation errors. Even redirects are returned as JSON instructions, so that the client only loses the form’s information on a successful POST.

The end result is that any validation/ModelState/returning of a View goes away. More important, any concerns of having to rehydrate a model that went through the form POST cycle. The first model was built in our GET action, the query handler, but there’s no guarantee that the model bound from POST form variables can just be passed to the view. This technique skips all that messiness of model rehydration and lets us only focus on success.

Towards commands

At this point, once I’ve removed all orthogonal concerns, I’m left with the “meat” of the action:

[HttpPost]
public ActionResult Edit(ConferenceEditModel form)
{
    var conf = _session.Get<Conference>(form.Id);

    conf.ChangeName(form.Name);

    foreach (var attendeeEditModel in form.Attendees)
    {
        var attendee = conf.GetAttendee(attendeeEditModel.Id);

        attendee.ChangeName(attendeeEditModel.FirstName, attendeeEditModel.LastName);
        attendee.Email = attendeeEditModel.Email;
    }

    return this.RedirectToActionJson(c => c.Index(null), "Default");
}

I could stop here as I’ve mentioned before, and most of the time, I do. But if I have even more things going on:

[HttpPost]
public ActionResult Edit(ConferenceEditModel form)
{
    _auditer.Audit(form);
    
    var conf = _session.Get<Conference>(form.Id);
 
    conf.ChangeName(form.Name);
 
    foreach (var attendeeEditModel in form.Attendees)
    {
        var attendee = conf.GetAttendee(attendeeEditModel.Id);
 
        attendee.ChangeName(attendeeEditModel.FirstName, attendeeEditModel.LastName);
        attendee.Email = attendeeEditModel.Email;
    }
    
    _noteRecorder.RecordNote(form, conf, NoteType.Edited);

    return this.RedirectToActionJson(c => c.Index(null), "Default");
}

And this sort of orthogonal code is spread across many actions, not refactorable into filters, then I really would rather have this sort of thing more easily composable. That’s exactly what a mediator and command pattern will give me. First, let’s define what a command and its handler are:

public interface ICommand<out TResult> { }

public interface ICommandHandler<in TCommand, out TResult>
    where TCommand : ICommand<TResult>
{
    TResult Handle(TCommand command);
}

It might seem rather strange that commands always have a result, but it’s much, much easier to deal with side effects of commands through return parameters than through some other means (global registry, static field, re-querying some object, collecting parameter, etc.). For commands that create an item, I usually want to redirect to a screen showing that item, very easily accomplished when I can get the created item and as for its ID.

This is a bit controversial, but don’t frankly care, as it’s the simplest thing that could possibly work. If I want to have a command that returns Void, I could steal a page from F# and have a Command base class that returns a Unit type:

public abstract class CommandHandler<TMessage> : ICommandHandler<TMessage, UnitType>
    where TMessage : ICommand
{
    public UnitType Handle(TMessage message)
    {
        HandleCore(message);

        return UnitType.Default;
    }

    protected abstract void HandleCore(TMessage message);
}

Where the Unit type simply represents “Void” (which unfortunately in C# is “special”. The Action/Func divide is the result.)

Our handler just moves the code out of the controller action into a handler:

public class EditHandler
    : ICommandHandler<ConferenceEditModel, Conference>
{
    private readonly ISession _session;

    public EditHandler(ISession session)
    {
        _session = session;
    }

    public Conference Handle(ConferenceEditModel command)
    {
        var conf = _session.Get<Conference>(command.Id);

        conf.ChangeName(command.Name);

        foreach (var attendeeEditModel in command.Attendees)
        {
            var attendee = conf.GetAttendee(attendeeEditModel.Id);

            attendee.ChangeName(attendeeEditModel.FirstName, attendeeEditModel.LastName);
            attendee.Email = attendeeEditModel.Email;
        }

        return conf;
    }
}

The mediator now needs an additional method to be able to process commands:

public interface IMediator
{
    TResponse Request<TResponse>(IQuery<TResponse> query);
    TResult Send<TResult>(ICommand<TResult> query);
}

Again, very similar to the Query method. I’ll leave out the implementation of our actual mediator implementation – it’s nearly identical to the Query example. So why two methods? Fairly simple – it’s a bit easier to deal with separate pipelines for queries and commands, as the potential extensions for these two pipelines might be different. I also might have different rules applied and so on.

Finally, our controller in its entirety:

public class ConferenceController : Controller
{
    private readonly IMediator _mediator;

    public ConferenceController(IMediator mediator)
    {
        _mediator = mediator;
    }

    public ActionResult Index(IndexQuery query)
    {
        var model = _mediator.Request(query);

        return View(model);
    }

    public ViewResult Show(ShowQuery query)
    {
        var model = _mediator.Request(query);

        return View(model);
    }

    public ActionResult Edit(EditQuery query)
    {
        var model = _mediator.Request(query);

        return View(model);
    }

    [HttpPost]
    public ActionResult Edit(ConferenceEditModel form)
    {
        var conf = _mediator.Send(form);

        return this.RedirectToActionJson(c => c.Show(new ShowQuery { EventName = conf.Name }), "Default");
    }
}

All very uniform, and completely pointless to test. In fact, my tests now focus on handlers, with simple model in/model out semantics. I don’t have to deal with action results, validation and so on. Each concern is separated into its own unit, composed together at runtime.

Simpler? For many apps, no. For larger apps, this sort of pattern is extremely valuable, as adding features to an application results only in adding files (except for some links and that shared controller). It’s not an architecture I put into all my applications, far from it, but it’s worth keeping in mind when you want to keep those controllers lean.

Where to from here

That controller looks awfully pointless, no? Yes, and no. I still want somewhere where I can deal with actual UI concerns, and sometimes building out ActionResults is complicated. Doing something like “controller-less actions” doesn’t really help there.

Otherwise, it’s worth looking at frameworks that directly support this sort of model of development, such as:

If there’s one thing I want to leave readers with it’s this – this series of posts isn’t about a single pattern to rule them all. I only use these techniques when the code’s shape dictates it, but not before. Pay attention to those code smells, keep your design flat, and be very, very judicious with abstractions.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Architecture, ASP.NET MVC, Patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://mhinze.com Matt Hinze

    Great series Jimmy. One of my favorite things about this way is that it really frees up the front end. In other words, I can care very, very little about ASP.NET MVC or web API or whatever framework I am using. And I have little reason to fret with any difficult or improperly designed extensibility points. We can write regular, idiomatic ASP.NET MVC on the edge. It becomes just the last piece of the puzzle.

    A lot of times our handlers are simple like this. Most times. But when they aren’t we have a great seam to inject a properly designed subsystem.

    One last note, we have found this scales in a couple ways. First, different people can work on the views and the handlers at the same time – just return a newed up view model from the controller while test driving the handler. That’s nice. Second, because we have these nice feature buckets with clean boundaries it’s easier to swap out the way one works. For example, we use mostly ORM but there’s one handler that drops down to Dapper. We can make finer grained technical choices and not pollute other parts of the system. PS Shortbus is container agnostic and handles async now.

  • TomasJansson

    Nice post Jimmy. You should look into Simple.Web, intro here: http://ianbattersby.github.io/blog/2013/09/02/5-days-of-simple-web-getting-started/. In simple.web you separate things even more with having one class per action/query. So far I’ve just been playing with it and I like it so far, especially their “REST support.”

    • jbogard

      Nuts, I forgot about that one! I’ll add it to the list at the bottom of the post

  • http://aashishkoirala.github.io/ Aashish Koirala

    I’ve been following this series closely – and have had a long-running thread in my mind every time I read through these: would this pattern be beneficial to the SPA model? Specifically, how well would it sit with a REST-based web API layer?

    As more and more people move towards more client-heavy applications using Angular or Ember and the controller layer becomes more and more purely web API, it would be interesting to see how well this pattern plays out in that model too.

    Just thinking through superficially, seems to me like it would work pretty well. Haven’t delved deeper than that though.

    • http://mhinze.com Matt Hinze

      I am currently using this approach in a Web API project, and it’s working quite well. We are finding that from the mediator’s perspective there is not much of a difference between commands and queries. In HTTP, even commands have results. From our client code (BaseController, in our case) we have two methods (QueryAsync and CommandAsync, their signatures are the same, but the wrap the mediator with different aspects).

      We write integration tests from the perspective of command and query handlers and don’t worry too much about testing the implementation details (OO/ORM vs procedural handlers).

      OO/ORM does simplify the handler authoring, but that is relegated to an implementation detail once under test. We also enjoy OO/ORM for seting up test data.

      We have a very thin subsystem that translates exceptions our handler throws to HttpResponseExceptions and converts results to 201s, etc.

      We have a “schemas” project that contains all the POCOs that will be serialized, and we have end to end tests (restsharp calls only) that consume that to smoke the entire API in business defined scenarios. Those end to end tests are super for us. In this org historically, other teams would improperly invoke a WCF endpoint and log a defect against the production team. With these tests we know it works, they are easily automated, help docs are generated, and they offer a great sample of how to consume the API.

      • http://aashishkoirala.github.io/ Aashish Koirala

        That sounds interesting. Any chance you could share the code for BaseController (or at least relevant snippets)?

  • confused

    Hi Jimmy,

    Could you please explain the usage of UnitType in C# as well in the context of the CommandHandler example please? I’m bit confused here..

    • jbogard

      Sorry, forgot to link there. UnitType represents “void” in F#, so that you can still return a value, that represents “Void”. The abstract class represents a void command handler, encapsulating the “Unit Type” business.

      • confused

        Hi, thanks for the reply. Would it be possible for you to post the link to the implementation gist of the UnitType? curious to see your take on that. Many thanks in advance.

      • James Nail

        So I guess using a class named “Void” would wreak havoc if you were forced to work in VB.net against your will (although it’s fine in C# as long as Void is capitalized). I prefer a class named “VoidType” (or something like that). I could see a lot of confusion around “UnitType” from the non-F# devs out there. (@mhinze:disqus, just a thought for ShortBus)

  • Michael

    Great reading.

    I found this approach is quite nice though I have some disagreements with it.

    First, correct me if I’m wrong, but this model state testing via ajax is not playing nice when you have js error or js disabled – it will return user a json instead of the same page with invalid fields. Which is why we need to return proper view from action in case of we got invalid model state on server. And thats brings another question – refilling model properties for displaying the page (drop down list items, ect.)

    Next, I don’t see how you’ll be able to push more complex validation errors back into view – for example, how will you display an error in Edit(ConferenceEditModel form) when you have a business requirement that there should be no two conferences with the same name? I don’t think it’s good solution to push such logic into separate validator since it’s really just a couple of strings if done within the handler (instead of a whole bunch of code in separate validator). I would rather throw a special exceptions for such cases directly from handle, then catch them all in action and fill the model state from them.

    I hope there will be more articles where you show how you’ve done that :)

    • http://mhinze.com Matt Hinze

      This is one question I have gone back and forth on, never finding a great answer. I think it boils down to idiomatic UI authoring vs. centralized business rules.

      I have done it both ways.

      1. Build a validation piece inside the handler infrastructure which knows how to communicate back to UI. You also need a piece inside the UI to read the errors and populate the UI’s state.

      2. Write (duplicate?) validation code in UI

      I lean towards #2 and idiomatic UI authoring. Although I gotta tell you, #1 was *really* slick once we got it working. The main problem with #1 was that it was still tied to our UI framework, we never built out a validation story for another UI. I’m sure it could be abstracted, but there is business analysis and requirements gathering to be done to verify that the rules would not change across UIs. For example, a user may not create a duplicate conference name, but it might be possible via the admin API. Same command, different rules. Who owns the rules and where are the seams at which the rules change?

  • Filip Kinský

    I find IMediator little bit dirty, because it hides dependencies on concrete CommandHandlers or QueryExecutors from the controller side. It feels quite similar to service locator. Why not depend on ICommandHandler and specific QueryExecutors from the controller? It would make dependencies more explicit in my opinion. What do you think?

    Anyway thanks for really interesting series.

    • jbogard

      The point is to hide dependencies on concrete handlers. You don’t care _how_ the command is handled, only that you have a tiny window through which to work with.

      Another advantage of a mediator is that you can provide a single point in which to manage the handler pipeline. It can be a bit tougher with only the handler interface to add orthogonal concerns to the mix (logging, security etc)

      • Filip Kinský

        ICommandHandler is no “concrete handler”, is it? I prefer not to hide dependencies in sake of cleaner and more straightforward design. You can easily have a single dependency on IMediator, but produce some god controller which invokes many types of commands. I really like to make dependencies explicit and clearly visible, but this could be just my subjective opinion of course…

        The ortogonal concerns should be rather handled in AOP way using IOC container features like Windsor Interceptors.

        But these are really just minor issues – I like the CQRS-inspired approach really much. I also ended using similar design in my last project. It really brings a lot of transparency and better overall view over application functionality.

        • jbogard

          It’s a concrete handler in that there’s an abstraction you’re exposing. Suppose there IS no ICommandHandler, your IMediator wouldn’t change. I’m not making dependencies less explicit, I’m encapsulating the concern of how to take a message and route it to something to handle the message. That might be an in-memory handler, it might be a function, it might be something else entirely. And if I want to extend the pipeline, say with events (IEventHandler), I have a mediator that encapsulates the pipeline. IoC can’t do that. But you do lose the ability to quickly know exactly who executes a handler. For me, that’s OK – I might have several classes execute as a result of a handler.

  • Zachariah Young

    What happens when you have a very complex UI that allows for updating multiple entity. In the example above maybe you edit the conference and want to create tracking the user making the change.

    Are you make separate calls for each command operation?
    Creating one command to handle all the changes?
    Or providing a method to pass a list of commands?

    • Vlad Kopachinsky

      Or providing a method to pass a list of commands? – of course need support composite command. We use code like are ( code from cshtml file )
      @(Html.When(JqueryBind.Click)
      .Do()
      .AjaxPost(Url.Dispatcher()
      .Push(new AddUserCommand { Id = “1″, Name = “Name” })
      .Push(new ApproveUserCommand { UserId = “2″ }))
      .OnSuccess(dsl => dsl.With(r => r.Id(containerId)).Core().Insert.Html())
      .AsHtmlAttributes()
      .ToButton(“Run”))

      More sample https://github.com/IncodingSoftware/MVD/blob/master/MVD.UI/Views/Home/Index.cshtml

    • jbogard

      The typical approach I take right now is to treat that as one command still. That way I still have just one success/fail operation as opposed to command 1 succeeding but command 2 fails. So I create a class that composes both commands, and then inside the handler delegate to different methods/classes.

      • Vlad Kopachinsky

        With shared transaction ? I mean if command 2 throw exception then command 1 rollback right ?

        • jbogard

          Yep!

  • Vlad Kopachinsky

    Our company use CQRS and found solution ( code name as MVD ) .
    MVD ( model view dispatcher ) is a design pattern to execute a Command / Query without writing an Action ( in Controller ).
    You can read about this on article ( http://blog.incframework.com/en/model-view-dispatcher/ ). MVD one part of open source project Incoding Framework ( https://github.com/IncodingSoftware/Incoding-Framework )

    • jbogard

      Ah, thanks, I’ll take a look!

      • Vlad Kopachinsky

        Thanks you. Let me know if you have any questions or suggestions. We have more acticle about our framework but not all translated.

        Also we work over NO-JS solution ( our declarative language IML http://blog.incframework.com/en/jqyery-style-vs-iml-style/ )

        P.S Your opinion and comment will be very interesting.

  • Luke

    How are you handling exceptions? I’ve just nuget’ed the latest ShortBus, and it would seem that any exceptions raised are getting eaten up and placed in the reponse from _mediator.Send() or _mediator.Request();

    Great posts BTW – I feel that I’ve learnt a lot from it. It’s already helped me clean up my application no end. Many Thanks.

    • jbogard

      My own ShortBus doesn’t do that. I let the exceptions bubble.

  • paulo ortins

    Hi Jimmy. How do you access Session in this architecture ?

  • Pingback: SapiensWorks | MvcPowerTools Preview: Query and Command Controllers

  • Farhad

    Hi

    Hope all is well.

    According to this post, what would the mapping look like?

    • farhad

      sorry..wrong post :)

  • Pingback: One Model In, One Model Out | The Skills Matter Blog

  • Pingback: Tackling cross-cutting concerns with a mediator pipeline | Jimmy Bogard's Blog