Web API versioning using Custom Header

by Sachin Singh


Posted on Monday, 18 May 2020

Tags: Web API Versioning Using Custom Header

This is the continuation of the Web API Versioning Series, in the previous three articles we have learned
  • why is Versioning required Read here and
  • Versioning using URI Read here
  • Versioning using Query String Read Here

In this article we will learn how to implement versioning using Custom Header. We already have two API Controllers :-
  1. SilverEmployeeController, which returns Employee's Name ,Id and Salary.
  2. GoldEmployeeController , which returns Employee's First Name ,Last Name, Id and Salary.

Our Clients know nothing about the real implementation, they just know that they are consuming EmployeeService and there exist two versions of the service. In order to consume the service they have to pass the version number too along with the URL, it's our duty to tell our clients how can they pass the version number. There are many ways with which version number can be passed like:-
  1. In the Form of routed data .(versioning using URI)
  2. In the form of query string (versioning using query string)
  3. In the form of Custom Header (versioning using custom header)
  4. In the form of Accept Header (versioning using accept header)
  5. In the form of Custom Media Types (versioning using Custom media types).

Web API versioning using Custom Header simply means the clients are going to specify the version number as the Custom Header

Versioning using Custom Header
Passing Version Number as custom Header

So, our work is to tell web API to select the appropriate controller based on the version number specified by the client as a custom version header.
  • If the client passes, X-EmployeeService-Version:1, then we have to tell web API to select SilverEmployeeService Controller.
  • If the client passes X-EmployeeService-Version:2, then we have to tell web API to select GoldEmployeeService Controller.

From the previous article, we know how web API selects the controller based on the information from URL, we also know how to override the default behavior of controller selection.

In the previous article, we have implemented a CustomControllerSelector. At the moment, this CustomControllerSelector is retrieving the version number for a query string parameter.

To implement versioning using a custom version header, all we have to do is change the logic slightly into the CustomControllerSelector class to read the version number from the custom version header instead of from a query string parameter.


    namespace MyFirstAPIProject.Custom
     {
    
        public class CustomControllerSelector : DefaultHttpControllerSelector
        {
            private HttpConfiguration _config;
            public CustomControllerSelector(HttpConfiguration config)
                : base(config)
            {
                _config = config;
            }

            public override HttpControllerDescriptor
                SelectController(HttpRequestMessage request)
            {
                // Get all the available Web API controllers
                var controllers = GetControllerMapping();
                // Get the controller name and parameter values from the request URI
                var routeData = request.GetRouteData();

                // Get the controller name from route data.
                // The name of the controller in our case is "EmployeeService"
                var controllerName = routeData.Values["controller"].ToString();

                // Default version number to 1
                string versionNumber = "1";
                string customHeader = "X-EmployeeService-Version";
                if (request.Headers.Contains(customHeader))
                {
                    versionNumber = request.Headers.GetValues(customHeader).FirstOrDefault();
                }
                

               
                if (versionNumber == "1")
                {
                    // if version number is 1, then prepend "Silver" to the controller name.
                    // So at this point the, controller name will become SilverEmployeeService
                    controllerName = "Silver"+controllerName;
                }
                else
                {
                    // if the version number is 2, then prepend "Gold" to the controller name.
                    // So at this point the, controller name will GoldEmployeeService
                    controllerName ="Gold"+controllerName;
                }

                HttpControllerDescriptor controllerDescriptor;
                if (controllers.TryGetValue(controllerName, out controllerDescriptor))
                {
                    return controllerDescriptor;
                }

                return null;
            }
        }
    
     }

The implementation is simple and straight forward, we are getting version number from Custom version header and accordingly changing the controller Name.

Now , run the application and fire two get request on the behalf of two different client like below and test the results.

Getting appropriate result based on version number
Versioning using Custom Header

As you can see ,for the X-EmployeeService-Version:2 we are getting list of GoldEmployee back ,it means our custom controller selector is successfully working and versioning is successful.