Skip to main content

How to implement RESTful API Versioning in ASP.NET Web API 2 using IHttpRouteConstraint

The only thing constant in life is change, and that is proved everyday in our industry, API’s are cool to extend the functionality of your application and expose it to other developers. The cool thing about IT and software, it’s that things changes quite rapidly and so it’s the technology, hence technology can change and the needs of your organisation can change, hence in order to keep serving this evolving needs and keep been relevant, your api might need to change also. Small changes can be accommodated within the initial version, but changes that will risked breaking the existing code, will required the need for versioning.


Implementing a custom IHttpRouteConstraint


According to msdn, a IHttpRouteConstraint simply Represents a base class route constraint. What then is a route constraint? A route constraint simply gets or sets a dictionary of expressions that specify valid values for a URL parameter.


public class ApiVersionRouteConstraint : IHttpRouteConstraint
  {

      public ApiVersionRouteConstraint(string apiVersions)

      {
          ApiVersions = apiVersions.ToLowerInvariant();
      }

      public string ApiVersions { get; private set; }

      public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
        {

          object value;

          if (values.TryGetValue(parameterName, out value) && value != null)

          {

              return ApiVersions.Equals(value.ToString().ToLowerInvariant());

          }

          return false;

      }

  }



This class inherits the IHttpRouteConstraint interface and implements the IHttpRouteConstraint.Match method, which will return true if the specified parameter equals the ApiVersions property that was initialised in the constructor, the value for the comparison will be derived from RoutePrefixAttribute, which we'll implement now.


Implementing a custom RoutePrefixAttribute


According to Msdn, a RoutePrefixAttribute is class that annotates a controller with a route prefix that applies to all actions within the controller.


public class ApiVersion1: RoutePrefixAttribute
  {
private const string RouteValue = "api/{apiVersion:apiVersionRouteConstraint(v1)}";
    private const string RouteValuePrefix = RouteValue + "/";

      public ApiVersion1(string routePrefix)

          : base(string.IsNullOrWhiteSpace(routePrefix) ? RouteValue : RouteValuePrefix + routePrefix)

      {

      }

  }



The purpose of implementing the above attribute is to encapsulate the api/v1 part of the template, so you can call directly pass the controller name as a parameter rather than copying the entire template.


[ApiVersion1("Jobs")]
public class JobsController : ApiController {

}


The above implementation is same as the implementation below, the only different is the encapsulation of api/vi part of the template.


[RoutePrefix("api/{apiversion:apiVersionRouteConstraint(v1)}/jobs")]
public class JobController : ApiController {

}


Summary

Using a custom IHttpRouteConstraint made it easy to constrain apiVersion parameter to a value of v1. The implementation is far from over, in another post i will be discussing how to implement a custom controller selector using IHttpControllerSelector and registering our ApiVersionRouteConstraint with a constraint resolver which the framework will need to instantiate the right constraints.

Comments

Popular posts from this blog

How to do partial update for HTTP APIs in ASP.NET CORE MVC with JSON Patch

JSON Patch is a format for describing changes to a JSON document. It can be used to avoid sending a whole document when only a part has changed. When used in combination with the HTTP PATCH method, it allows partial updates for HTTP APIs in a standards compliant way. A JSON Patch document is just a JSON file containing an array of patch operations. The patch operations supported by JSON Patch are “add”, “remove”, “replace”, “move”, “copy” and “test”. The operations are applied in order: if any of them fail then the whole patch operation should abort.
The JSON Patch supports the following operations:
Add - Adds a value to an object or inserts it into an array.Remove -  Removes a value from an object or array. Replace - Replaces a value. Equivalent to a “remove” followed by an “add”. Copy - Copy a value from one location to another within the JSON document. Both from and path are JSON Pointers. Move - Move a value from one location to the other. Both from and path are JSON Pointers. Test - Te…

Top 2 ways to pass parameters to a view component

View components is a feature of ASP.NET Core MVC, that’s similar to partial view and child actions, one cool thing about view component it allows you to create reusable components with or without logic.
The purpose of this post is to show you how to pass view component as a parameter when invoking it from view and controller.
Another  cool thing about View Components is that it separates the logic of which markup to display from the markup itself. It’s a class that inherits from View component and implements Invoke and InvokeAsync Methods, the return type can vary, and that depends on largely what you intend to render.
Example of Simple View Component
public class ItemViewComponent : ViewComponent
{
   public IViewComponentResult Invoke()
   {
       return View();
   }
}
To use the View Component, we have to invoke the Item View component from _Layout.cshtml

How to implement multi-tenancy with subdomains using Route Constraint in ASP.NET MVC

According to Wikipedia, The term "software multitenancy" refers to a software architecture in which a single instance of software runs on a server and serves multiple tenants. A tenant is a group of users who share a common access with specific privileges to the software instance. With a multitenant architecture, a software application is designed to provide every tenant a dedicated share of the instance - including its data, configuration, user management, tenant individual functionality and non-functional properties. Multitenancy contrasts with multi-instance architectures, where separate software instances operate on behalf of different tenants. By giving companies, access to a tenant through a subdomain of choice, will help to personalise the experience more and gives a sense of ownership to each tenant. This will go along way to bring consistency in there branding.
Implementing Route Constraint
You use route constraints to restrict the browser requests that match a partic…