I mentioned it in passing a few times, but I've been playing around with a twist on some of the main-stream technologies in the web world. REST, AOP and template-driven MVC. I've been playing around with this on the no-recruiters platform, which I'm using as a development guinnea pig. It's a live site, the traffic is (for now) low, and so it both makes me drive it to compeltion and gives me a chance to fiddle and figure out how a framework is from the usability side.

I've been calling it Bistro (that's what happens when developers try their hands at marketing). Bistro is actually the russian word for "quick", and so the idea is that this another extension for workflow server that lets you quickly build applications.

Back to the idea. The concept is straight-forward enough.

  • Build applications where URLs are effectively method invocations.
  • Allow an AOP-style syntax for defining cross-cutting controllers that service these method invocations.
  • Move away from MSFT's client-server abstraction model aka WebForms, and use a templating engine. Right now it's the NVelocity port (the original, not the Castle fork). If this gains traction, there are a few features I'd like to implement (I like the template inheritance model in Django, etc), so I'd like the freedom of an independent fork.
  • Build this on top of workflow to take advantge of the VS.NET integration, the ORM pieces, and the logging facilities.

Example (and I'll use some of the no-recruiters (aka nr) nomenclature throughout).

I have a function called search. My search method is going to be /content/search/resume. This method needs a few things to happen (yay, classic AOP examples). First, we need to log this method call. Second, we need to make sure that you have access to perform this method call. Third, we need to prepare the search results, capitalizing on the fact that the difference between a resume search and an ad search is a parameter, and finally we need to render the results.

High level, this breaks down as follows

  • Define a controller called "AccessValidator" and bind it to the / context.
  • Define another controller, "RequestLogger" and also bind it to the / context.
  • Define a controller "Search", and bind it to the /content/search/{searchType} context (I'll touch upon parameterized contexts in a second)
  • Create a template file /content/search/resume (this assumes that we've addressed the IIS no-extension URL rewrite issue)

A few explanations. Binding - just like it sounds. We define that a given controller is executed when a url matches its bind point. Bind points can have wild-cards, but if they don't, are root-relative URL fragments. Arbitrary elements can be parameterized, and parameterized elements are passed into matching controllers as parameters. Also, the binding definition lets you control the order in which things are run (think of point-cut definitions - before, insteadof, etc).

So in the example, here's how the processing would go.

  1. Request comes in for /content/search/resume
  2. AccessValdiator is called
  3. RequestLogger is called
  4. Search controller is called, given a parameter of searchType = 'resume'. This controller performs the search, and places the results onto a context variable.
  5. /content/search/resume.vm (or .bistro) template is pulled up and rendered, using the search results present in the context variable.

I'll be the first to admit that a lot of this is a game of semantics, but in larger systems semantics mean quite a bit. Additionally, much of the advantages of AOP apply, without the major disadvantage of breaching OO Encapsulation.

The utility of REST here is to make AOP useful. By definining meaningful, method-like URLs, resultinng applications become much more susceptible to AOP. Point-cuts become a lot more general and the definitions are more concise. Additionally, we solve the problem of "i don't want to encode template names in my code". The common problem of how do I transfer control without being dependent on what the target is. In this nomenclature, you don't deal with specific templates, you are just requesting that an action be performed. What that action means, and how it's represented to the end user is up to how the action is implemented.

 More to come...