Related Service

.Net Development

Know more about our .Net Development Services

Learn More

Different Methods of API Versioning & Routing in ASP.Net Core

Published: Nov 11, 2020

In the ever-changing business world, the only constant is ‘change’. In the custom software development business, the change is implemented by versioning. Versioning is a process of adding improvements in an existing model while keeping the current model too and essentially selling both the products differently at different prices. Improving the functioning of the application developed has its vision associating with increasing overall productivity and efficiency of the developed application. There is no wonder drug behind versioning, though it is an essential factor in the web application. In ASP.net Core technology API versioning allows users to create API without affecting the previous set of users, adding some new APIs on top of existing ones. Let’s start with how to set up for new API versioning.

Setup

Start with the Installation of the Nuget package from Nuget Package Manager or Package Manager Console in the API project as shown below

Microsoft.AspNetCore.Mvc.Versioning

Write the below code in Startup.cs in the ConfigureService method.

services.AddApiVersioning(config =>
            {
                config.DefaultApiVersion = new ApiVersion(1, 0);
                config.AssumeDefaultVersionWhenUnspecified = true;
                config.ReportApiVersions = true;
                config.ApiVersionReader = new HeaderApiVersionReader("api-version");
            });

AssumeDefaultVersionWhenUnspecified -When the API version of the current application is not specified in the request then set the value as true to get the default API version number.

ReportApiVersions – If you set the value of ReportApiVersion as true, then the information of the version is generated and displayed in the header section as shown in the image below.

ReportApiVersions

There are mainly three different methods/techniques in Asp.net core technology for Web API Applications.

Versioning with URL Routing

In Controller add API method add as below for version 1.0

Add API

[HttpGet]
        [Route("[controller]", Order = 1)]
        [Route("api/v{version:apiVersion}/[controller]", Order = 2)]
        [ApiVersion("1.0")]
        public IEnumerable<Person> Get()
        {
            var person = _personService.GetList();
            return person;
       }

Call above Api with version 1.0 in postman, as given in below image and check result

Call API

In Controller add API method add as below for version 2.0

Add API

 
        [HttpGet]
        [Route("[controller]", Order = 1)]
        [Route("api/v{version:apiVersion}/[controller]", Order = 2)]
        [ApiVersion("2.0")]
        public Person GetV1_1()
        {
            var person = _personService.GetList().FirstOrDefault();
            return person;
        }

To call, above API with version 2.0 check the below image

To call

Using this methodology, the existing consumers will have to change the endpoints to validate recently developed changes. Ideally, we need to change the URL routes, otherwise, it can lead to major disadvantage. To overcome this drawback, we have two other ways to achieve versioning.

Versioning using HTTP Header

In this method, the version needs to be passed to the HTTP Header. One more option is required in Startup.cs to add an entry in HTTP Header.

HTTP Header

services.AddApiVersioning(config =>
 
            {
                // default API Version set as 1.0
                config.DefaultApiVersion = new ApiVersion(1, 0);
                // If the API version not defined in the request, default API version will be used.
                config.AssumeDefaultVersionWhenUnspecified = true;
                config.ReportApiVersions = true;
                config.ApiVersionReader = new HeaderApiVersionReader("api-version");
            });

The version can be passed as Http Header through the Postman method and the results can be displayed as shown in the below image. If the version is not passed into the header, the default version set in Startup.cs will be used. Here’s the default version used is version 1.0.

Default version

Versioning using the Query parameter

With this approach, the users can pass versions in the query string as displayed in the below image. To use this, users need to configure the first header version and remove all others from ConfigureService in Startup.cs.

Query parameter

Deprecating API Version

We can deprecate the API version which is no longer used. We do not need to remove the version, as it can be used somewhere. We can mark it as deprecated, so when API is called, the header information displays that the called API is deprecated.

Deprecating API Version

[HttpGet]
        [Route("[controller]", Order = 1)]
        [Route("api/v{version:apiVersion}/[controller]", Order = 2)]
        [ApiVersion("1.0", Deprecated = true)]
        public IEnumerable<Person> Get()
        {
            var person = _personService.GetList();
            return person;
       	        }

The users will find the depreciated version information as shown in the image below.

Depreciated version

Routing in Web API

Routing in Web API allows users to match the upcoming HTTP requests, after performing the match, the requests are dispatched to the executable endpoints of the application. These endpoints are configured at the beginning of the application configuration. The endpoint can be matched by extracting values from the requested URL and retrieving those values to further process ahead. If the users have the endpoint information from the app through routing they will also generate URLs that would map to endpoints.

Rasor Pages, Endpoint-enabled, Controllers, Razor Pages, Delegates, SignalR and lambdas registered with routing can be used to configure routing for Apps.

Setup for Routing is registered in middleware in Startup.cs in Configure method. UseRouting and UseEndpoints are the two ways to register Routing

  • UseRouting configures the route that matches with the middleware pipeline. After looking into the set of endpoints specified in the app, the middleware then selects the most appropriate match based on the request called.
  • UseEndpoints is used to configure the endpoint execution to the middleware pipeline. It runs the delegate related to the chosen endpoint.

Endpoint

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
 
            app.UseHttpsRedirection();
 
            app.UseRouting();
 
            app.UseAuthorization();
 
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

Attribute Routing

Attribute routing enables users with an attached attribute or route, to a specific controller or action method. It is quite simple to apply Attribute routing, you can simply apply routing in Route attribute which acts as a controller and runs a method. It Introduced from Web API 2 and now it is the most used Routing type in RESTful API development. Users can discriminate between attribute routing from conventional routing by allowing them to have control over the URIs in the APIs. Also, Attribute routing can be used in achieving API Versioning, multiple parameter type patterns, and overloading URI segments.

To enable attribute routing in API, config. MapHttpAttributeRoutes() must be called in WebApiConfig.

[Route("[controller]", Order = 1)]

The users can replace the controller name with the Token name by defining the route from the action or class.

All HTTP Verbs can be used as route templates.

Every action associated with HttpGet attribute will be matched with Http GET requests only.

If [HttpGet] request, requested with POST method return 404 Not Found error.

There is an internal tree built that continuously matches all the endpoints. If you use Route then they are configured using Order property. The route entries are processed in ascending order based on Order property. In special cases, routes get a chance of execution before the general routes.

 
[Route("[controller]")]
 
public class PersonController : ControllerBase

The above code block matches with the “/person” URL

Below is the example of pattern matching in URL

Pattern matching

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
 
            app.UseHttpsRedirection();
 
            app.UseRouting();
 
            app.UseAuthorization();
 
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

The above code block generated is for multiple parameters and multiple routes combined in a single method. The Order parameter is defined here and can be matched with the order during the match route process.

  • /person – will be matched with first route
  • /api/v1.1/person/ – will be matched with second route
  • api/v1.1/person/daxa – will be matched with the third route it will pass the value in name parameter
  • api/v1.1/person/us/test – will be matched with the fourth route, it will pass values for both name and email parameters.

Comments

  • Leave a message...

Related Articles

Things you must know before choosing Power BI

Nov 26, 2020

What are ORMs and How does it work?

Nov 24, 2020

Introduction of Azure DevOps Pipelines

Nov 19, 2020