More complex routing

Topics: Web Api
Mar 22, 2011 at 4:35 PM


I'm working on implementing a RESTful service and been looking at the frameworks available to .NET and was hoping to use the upcoming WCF HTTP framework.
Unless I'm misunderstanding something about the framework, the routing just isn't powerful enough for my needs.  You are binding the first path in a URI to a service-like class instead of modeling URIs to resources.  OpenRasta does a far better job at this currently, as does ASP.NET MVC.
This kind of restriction will affect how people design their REST APIs, and IMO a framework shouldn't dictate how you model your resources.
You have some nice things in the framework and I would love to use it, but unless you can offer more powerful routing I'm afraid I wont.


#1 Persons/{personId}
#2 Mails/{mailId}
#3 Persons/{personId}/Mail
#4 Companies/{companyId}/Mail

Routes #1 and #2 are easy to map in your framework, but I want routes #3 and #4 to map to a MailList resource handler/controller.  That class would then have methods to return a collection (of URIs) for both persons and companies.
Currently I would have to "pipe" the requests first through the PersonController, and call the MailListController from PersonsController? This would make the whole API class structure resemble a spaghetti mess rather than separate classes :)

The above example is easy to implement in ASP.NET MVC, so why cant you adopt the routing used there?

Mar 22, 2011 at 4:41 PM

I totally agree with this post. Having to do the piping SiggiG is talking about is painful considering maintainability of the code. Is there a valid reason why WCF HTTP doesn't use the same routing engine as MVC?

Mar 22, 2011 at 5:59 PM

We do support 3 and 4 through uri templates. As far as the route itself it has to be static or empty. This is something we are working on in the future, but it is a non-trival amount of work as our current host depends on a base address which is static which the address passed in ServiceRoute maps to. WCF supports uri templates because it can be hosted in other environments than ASP.NET, including on top of IIS directly or self host.

We combine the route prefix along with the uri templates specified in the service class. You could also pass an empty uri to AddServiceRoute and put the full uri in the template i./e. "persons/{personId}/Mail".

Basically your person class and companies class look like this to achieve the same result.

public class Persons {
  public IEnumerable<Person> Get(stirng personID) {

public class Companies {
  public IEnumerable<Company> Get(string companyID) {

//in the global.asax
Mar 22, 2011 at 6:15 PM

Fear not.  The current mechanism to map operations to URIs is just the default behaviour that was built to mirror the existing System.ServiceModel.Web.  The extension points are in place to dynamically build contracts and connect operations to URI templates.  Unfortunately, you will either have to build it yourself, or be patient.  The initial framework needs to be put in place before we can build more fancy stuff in top.

Step 1 is to get the HTTP infrastructure right.  Step 2 will be to build RESTful frameworks on top.

You are not alone in your desire for a more flexible routing mechanism.  From what I have seen, this should be completely feasible to do.

Mar 22, 2011 at 6:29 PM

Thank you very much for a quick reply!  I didn't know you could use an empty uri in AddServiceRoute, but I guess that comes with an overhead since the framework would need to look at all the classes involved to figure out the correct method?  But that will serve my purpose for now.

I'm also very happy to hear that this is just the first step, and I'm looking forward to the next steps... until then, I should be able to use the workaround Glenn posted.

Thanks again!

Mar 22, 2011 at 6:43 PM
Edited Mar 22, 2011 at 6:45 PM

SiggiG that overhead is there only at initial startup. We look for that information once as the service host is being configured and we build a map which our operation selector uses. It is not a continual tax.