Handlers – A useful FubuMVC Convention

Update

These conventions have been pulled into FubuMVC.Core and are no longer in a separate repository.

Background

One of the little known treasures of FubuMVC is its highly extensible route generation mechanism. The default policy is great for most cases. But when it falls short, you get a chance to make use of this fantastic little gem: IUrlPolicy.

So if the default policy (configured through the DSL) is great, where does it fall short? It’s not there’s anything wrong with using the DSL-based configuration for your routes. I just like to approach things a little differently.

Routing by Feature/Story

Let me see if I can get point across nice and strong:

I don’t like separating files that are closely related to each other. Period.

The Bad

First, I’ll give you an example of how I don’t like to do things:

No Bueno

I’m not sure where this comes from – though my suspicions tell me that they stem from the understanding of separation of concerns as they relate to MVC. The idea here is that you have your controller in one folder, models in another folder, and views in yet another folder. This way you can run around your solution trying to find your files.

The Ugly

That isn’t even the core of the issue, though. Look at the Account directory under Views:

  • ForgotPassword
  • LogIn
  • PasswordReset
  • Verified

We can assume here that each one of those views has a corresponding GET and an optional POST method in the AccountController. These are related, yes, I’ll give you that. However, let me ask you this:

If the logic of how passwords are reset changes, should you have to change anything for how you login?

Well, that’s debatable. I can see how you may have to change some logic to accommodate those logic changes. However, should be FORCED to if the logic remains the same?

My whole point is: why are these in the same class? And what’s the use of putting them into these arbitrary folders?

The Good

As I mentioned, I don’t like separating files. So what do I like? Let’s use the following url as an example:

posts/2011/7/hello-world

Now let’s consider a new structure:

all-good

The HandlersUrlPolicy:

Now we’ll walk through the important things here from the above diagram:

1. Handlers namespace and HandlersMarker

The HandlersMarker is a static type used to indicate the root of the Handlers namespace.

2. get_Year_Month_Title_handler class

This class exists within the Posts namespace. The HandlersUrlPolicy starts by building up routes based on namespacing (stripping away the root namespace as marked by the HandlersMarker). So for the Posts namespace, we start with “posts”.

The name of the handler is very important here and there are two ways to name your handlers: 1) Basic names or 2) Route-constrained names.

For both of these, the following rule is applicable:

Your handlers must start with the HTTP verb they apply to (e.g., GET, POST)

Basic Names

<HTTP VERB>Handler (e.g., GetHandler)

The basic handler convention uses the current route definition and applies the appropriate HTTP constraint. So if you had a GetHandler under the Posts namespace, you would have: “posts/ (GET)”. Not helpful in this situation, but useful in others.

Route-contrained Names

<HTTP VERB>_<PropertyName>_handler (e.g., get_Year_Month_Title_handler)

When using this naming scheme, the HandlersUrlPolicy will apply route inputs and constraints to your route to build up pretty urls like our example from above:

posts/2011/7/hello-world

The idea now is to have a Handler, input model, output model, and a view within the same namespace. Since the namespaces are used to make up the routes, you should be able to find these fairly easily.

How do I use this?

This is part of FubuMVC.Core. As I mentioned earlier, the convention uses static types as a basis for determining the root namespaces for the routes. The extension method for applying this convention takes in a params Type[] markerTypes which allows you to pass in the types used to indicate these roots. You can take a look at the tests to see it in action.

Of course, an example would be (from within your FubuRegistry):

ApplyHandlerConventions<MyHandlerMarker>()

Related Articles:

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

About Josh Arnold

Josh is team lead at Extend Health and a principal developer on the Fubu-family of frameworks. He is a proud husband, terrified but excited father, passionate software guy and coach, closet musician, aspiring man of God, and a perpetual learner.
This entry was posted in General and tagged , . Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #903

  • http://twitter.com/hcoverlambda Mike O’Brien

    I’ve really been digging the handler approach and the conventional routing. Fubu really enables cohesion and loose coupling. It makes me throw up a little bit in my mouth every time I see an ASP.NET MVC controller now. Going from ASP.NET MVC to Fubu feels like going from Dollar Store tools to precision Snap-On tools.

  • http://twitter.com/hcoverlambda Mike O’Brien

    I’ve really been digging the handler approach and the conventional routing. Fubu really enables cohesion and loose coupling. It makes me throw up a little bit in my mouth every time I see an ASP.NET MVC controller now. Going from ASP.NET MVC to Fubu feels like going from Dollar Store tools to precision Snap-On tools.

  • http://sm-art.biz Artëm Smirnov

    Why the Handlers folder? It sure looks like the Controllers folder of you-know-what. Besides, it does contain other things like Views and Models.

    • Anonymous

      @Artem,

      Just trying to make things slightly relate-able. But no, I don’t usually do this.

      I usually slice my routes/namespaces via features – that way grouping views, handlers, and models makes a little more sense.

      The ApplyHandlerConventions takes in params of Type so you can specify multiple root markers to handle however the hell you want to set everything up.

  • Pingback: Ten Signal Blog | Ten Signal Blog

  • Pingback: SapiensWorks | Asp.Net Mvc Routing By Convention