Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebApi routes with same routeTemplate with version constraint

I'm building an api using WebAPI. What I'm shooting for is creating an external library per version of the API which the WebAPI app will query when registering its routes in WebApiConfig

Example: Api.v1 and Api.v2


They will share similar functionality but based on version passed in the header it will choose the proper API Version:

/{controller}/{action} - HTTP-HEADER: version=1 maps to Api.v1.Controller/Action

/{controller}/{action} - HTTP-HEADER: version=2 maps to Api.v2.Controller/Action


The goal is to avoid prefixing /{ver}/{controller}/{action}. I know that having routeTemplates with the same value is not supported, but I thought I could bind the route to a specific namespace and a constraint might help settle which is matched:

namespace Api.v1
{
    public static class Routing
    {
        public static void MapRoutes(HttpConfiguration config)
        {
            IHttpRoute r = config.Routes.MapHttpRoute(
                name: "",
                routeTemplate: "{controller}/{action}/{id}",
                defaults: new 
                {
                    id = RouteParameter.Optional, 
                    namespaces = new string[] { "Api.v1.Controllers" } 
                },
                constraints: new VersionConstraint(2)
            );
        }
    }
}

public class VersionConstraint : IRouteConstraint
{
    int _version;
    public VersionConstraint(int version)
    {
        _version = version;
    }

    public bool Match(
        HttpContextBase httpContext, 
        Route route, 
        string parameterName, 
        RouteValueDictionary values, 
        RouteDirection routeDirection)
    {
        int version;
        int.TryParse(httpContext.Request.Headers["version"], out version);
        return version == _version;
    }
}

Attempting to inject the namespaces for each route hasn't really helped either. The DataTokens property is null and readonly.


Any idea how to do what I'm doing? Any way to have the same route map to different controllers of the same name but with different functionality and namespace?

like image 907
hunter Avatar asked Oct 18 '12 16:10

hunter


1 Answers

Take a look at Versioning ASP.NET Web API Services Using HTTP Headers, this appears to answer your question on how to route based on the precense of HTTP headers.

You replace the default controller selector with a custom IHttpControllerSelector that selects the correct controller based on the HTTP header.

like image 123
Oppositional Avatar answered Oct 14 '22 14:10

Oppositional