This article was originally published on my blog.
In this article, we will learn how to version ASP.NET Core Web API and some different ways of versioning the API. We will also create a simple Web API and implement the versioning.
Before implementing the versioning, we have to first understand why we need to version API. While working on an existing application or creating a new one, we may create multiple APIs that may be consumed by many clients. When the business has started to grow and expand, new requirements arise. Due to this, we may need to provide more functionality in the existing APIs. However, existing Web API can be consumed by many clients so how to implement the new feature without impacting the existing consumers? We can solve this problem by versioning our API.
Create ASP.NET Core Web API
Prerequisites
- Visual Studio 16.4 or greater
- .NET Core 3.1 installed
- Postman for testing Web API(If you don't have already you can download it from here)
Open Visual Studio and click on File -> New -> Project. Select ASP.NET Core Web Application template and click on the Next button
Give a name to the project and click on the Create button
Since we have to create an API, select API and click on the Create button.
That's it. You have created your Web API in ASP.NET Core.
In our project, we have one controller create by default named as WeatherForecastController. The next step is to run the application and call the WeatherForecastController API using postman. Hit F5 to run the API which will open a default browser. Open a postman and type the URL "https://localhost:44381/weatherforecast".
You can see that we have not implemented the versioning yet in the controller. I am going to use this API in the next part of the article where we will see different ways to implement versioning of API.
Different ways of Versioning Web API
We can do versioning of Web API using the following methods:
- Query string
- URL
- HTTP header
There are other ways as well, like accept-header and content type, but in this article, we are going to focus on the above 3 methods.
To do versioning in ASP.NET Core Web API, first, we have to install the below the Nuget package which will provide necessary methods for versioning. Right-click on the solution and click on Manage Nuget Package and search for package "Microsoft.AspNetCore.Mvc.Versioning" and install it.
Once the NuGet package is successfully installed, then the next step is to open Startup.cs and add the below code in the ConfigureServices method.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddApiVersioning(x =>
{
x.DefaultApiVersion = new ApiVersion(1, 0);
x.AssumeDefaultVersionWhenUnspecified = true;
x.ReportApiVersions = true;
});
}
Let's understand the above code that we added.
Line #6 - DefaultApiVersion is used to set the default version to API
Line #7 - This flag AssumeDefaultVersionWhenUnspecified flag is used to set the default version when the client has not specified any versions. If we haven't set this flag to true and client hit the API without mentioning the version then UnsupportedApiVersion exception occurs.
Line #8 - To return the API version in response header.
So if we hit the same API, we can see the default version in the response header.
Before discussing about different types, let's create two controllers (i.e EmployeeV1Controller and EmployeeV2Controller) as shown below.
EmployeeV1Controller.cs
using Microsoft.AspNetCore.Mvc;
namespace api_versioning_demo.Controllers
{
[Route("api/employee")]
[ApiController]
public class EmployeeV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new OkObjectResult("employees from v1 controller");
}
}
}
EmployeeV2Controller.cs
using Microsoft.AspNetCore.Mvc;
namespace api_versioning_demo.Controllers
{
[Route("api/employee")]
[ApiController]
public class EmployeeV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new OkObjectResult("employees from v2 controller");
}
}
}
Query String-Based Versioning
In the case of query string based versioning, we have to specify the API version in the query string to call the specific controller. Now we mention the specific version to each controller using [ApiVersion(version_name)] attributes. So our controller looks like the code below:
using Microsoft.AspNetCore.Mvc;
namespace api_versioning_demo.Controllers
{
[ApiController]
[ApiVersion("1.0")]
[Route("api/employee")]
public class EmployeeV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new OkObjectResult("employees from v1 controller");
}
}
}
using Microsoft.AspNetCore.Mvc;
namespace api_versioning_demo.Controllers
{
[ApiController]
[ApiVersion("2.0")]
[Route("api/employee")]
public class EmployeeV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new OkObjectResult("employees from v2 controller");
}
}
}
We can call controller using the below routes with the query string method.
To call EmployeeV1Controller, we have to hit as https://localhost:44381/api/employee?api-version=1.0
For EmployeeV2Controller we have to type: https://localhost:44381/api/employee?api-version=2.0
URL based Versioning
In this type of versioning, we can define versions in a URL so that it is more readable. Most users prefer this type over other types. You can to URL based versioning by changing the routs as [Route("api/{v:apiVersion}/Values")].
Let's modify the Route attribute in our both controller, as follows.
using Microsoft.AspNetCore.Mvc;
namespace api_versioning_demo.Controllers
{
[ApiController]
[ApiVersion("1.0")]
[Route("api/{v:apiVersion}/employee")]
public class EmployeeV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new OkObjectResult("employees from v1 controller");
}
}
}
using Microsoft.AspNetCore.Mvc;
namespace api_versioning_demo.Controllers
{
[ApiController]
[ApiVersion("2.0")]
[Route("api/{v:apiVersion}/employee")]
public class EmployeeV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return new OkObjectResult("employees from v2 controller");
}
}
}
To call EmployeeV1Controller, we have to hit as https://localhost:44381/api/1.0/employee
To call EmployeeV2Controller we need: https://localhost:44381/api/2.0/employee
HTTP Header-Based Versioning
In this type, we have to send the version in the Http header when we call the controller. So open the Startup.cs and add the below line of code into services.AddApiVersioning method. Also, delete the version mentioned in routes.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddApiVersioning(x =>
{
x.DefaultApiVersion = new ApiVersion(1, 0);
x.AssumeDefaultVersionWhenUnspecified = true;
x.ReportApiVersions = true;
x.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
}
Now enable the Http herder versioning type. When a client consumes the API, they have so send x-api-version into the header with specific version value to call the correct controller.
Conclusion
In this article, I have explained API Versioning, why we need to versioning, and different types of versioning. Also, I demonstrated an example of each type of versioning. I really hope that you enjoyed this article, share it with friends and please do not hesitate to send me your thoughts or comments.
You can follow me on twitter @sumitkharche01
Happy Coding!!
Top comments (7)
URL-based versioning is generally the easiest to implement without worrying about special cases. Querystrings and headers can lead to issues when dealing with reverse proxies and caches, but URL-based versioning tends to have less complications.
I feel like the best way to do it is to let an API Gateway handle it for you!
Amazing post Sumit!
Thanks Ankit
Great post, Sumit. ๐
I also recommend Microsoft's documentation on versioning - it has helped me a lot ๐
Very helpful Sumit๐
Very nice post, personally I have always used url based versioning but it's nice to see other options.
Thanks Patricio