Related Blogs
1. Introduction
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 associated 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 an 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 web API versioning.
2. What is API Versioning?
When it comes to deploying an API for your .NET Core project, there has to be a checklist of the features that are necessary for this process. One such feature that tops this list is to implement API versioning in ASP.NET Core. It is a very essential approach to anticipate all the changes that may be essential after the API is published and clients start using it. This means that once the API is published to a production server, the ASP.NET core development team has to be very careful with any future changes they make. The reason behind it is that the new changes made by the developer must not break the existing client applications that are using the API. And this is why the concept of API versioning came into the picture. The versioning semantics stated in the Microsoft REST Guidelines are followed by the default API versioning configuration.
API versioning in ASP.NET core is an approach that enables different clients to get distinct implementations of the same controller base when a request is sent or a URL path is entered. So, creating an API that has multiple versions that can behave differently is essential. By following this approach, the client requirement may change with time but there is no compromise seen when it comes to the availability and integrity of the data for the existing client apps.
3.Methods of ASP.NET Core API Versioning & Routing
1. Setup
Start with the Installation of the Versioning Nuget package from Nuget Package Manager or Package Manager Console in the API project as shown below
Microsoft.AspNetCore.Mvc.Versioning
Write the following 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"); }); |
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.
There are mainly three different methods/techniques in Asp.NET core technology used by asp.net core development company for developing Web API Applications.
2. Versioning with URL Routing
In Controller add API method add as below for version 1.0
[HttpGet] [Route("[controller]", Order = 1)] [Route("api/v{version:apiVersion}/[controller]", Order = 2)] [ApiVersion("1.0")] public IEnumerable Get() { var person = _personService.GetList(); return person; } |
[HttpGet] [Route("[controller]", Order = 1)] [Route("api/v{version:apiVersion}/[controller]", Order = 2)] [ApiVersion("1.0")] public IEnumerable Get() { var person = _personService.GetList(); return person; }
Call above Api with version 1.0 in postman, as given in below image and check result
In Controller add API method add as below for version 2.0
[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; } |
[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
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 disadvantages. To overcome this drawback, we have two other ways to achieve versioning.
3. 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.
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"); }); |
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.
4. Versioning using the Query parameter
With this approach, the users can pass API 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.
5. 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 an API is called, the header information displays that the called API is deprecated.
[HttpGet] [Route("[controller]", Order = 1)] [Route("api/v{version:apiVersion}/[controller]", Order = 2)] [ApiVersion("1.0", Deprecated = true)] public IEnumerable Get() { var person = _personService.GetList(); return person; } |
[HttpGet] [Route("[controller]", Order = 1)] [Route("api/v{version:apiVersion}/[controller]", Order = 2)] [ApiVersion("1.0", Deprecated = true)] public IEnumerable Get() { var person = _personService.GetList(); return person; }
The users will find the depreciated version information as shown in the image below.
6. 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 the 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.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
7. 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 supported 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)] |
[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 the 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 |
[Route("[controller]")] public class PersonController : ControllerBase
The above code block matches with the “/person” URL
Below is the example of pattern matching in URL
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } |
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.
4. Conclusion
In this blog post, we have explored various types of versioning for ASP.NET Core Web API applications. Essentially we started with URL routing versioning and then we have comprehended the versioning within HTTP Headers. Lastly, we have discussed other and essential choices such as deprecating API, routing in API, and Attribute API with query parameters.
Also, both http header and query param techniques do not affect the current consumers of Web API. However, if you take the URL routing method, you need to edit all the actual endpoints of the API.
Vishal Shah
Vishal Shah has an extensive understanding of multiple application development frameworks and holds an upper hand with newer trends in order to strive and thrive in the dynamic market. He has nurtured his managerial growth in both technical and business aspects and gives his expertise through his blog posts.
Subscribe to our Newsletter
Signup for our newsletter and join 2700+ global business executives and technology experts to receive handpicked industry insights and latest news
Build your Team
Want to Hire Skilled Developers?
This article provides a comprehensive overview of API versioning and routing in ASP.NET Core. For those who are new to API versioning and routing, this article will definitely be helpful in understanding these topics. Thank you for sharing this article.