API Versioning in Dot Net Core

API Versioning in Dot Net Core

APIs have long been the programmer’s tool of choice for communication between applications. Now, they are the basis of new services and business strategies, and the new distribution channel for products and services.

If you are building the Restful services in the .Net core platform then as a developer you must be aware of the API versioning concept, and the good thing here is, the platform itself had Nuget packages where the versioning was controlled.

Why and What happens when we use the version for the APIs? consider an example you have developed an API and deployed it then after some days you got one different requirement that you need to add some new functionality to it, So as a developer it is not a good practice to disturb the existing code (remind about the SOLID principles here), instead of changing the existing code base, you can create a version for the API and then add the new functionality over there. In this way both the old and newer versions of the APIs are maintained.

Versioning was a very important and a good handy thing when you have n number of APIs which are created for web-based applications and for Mobile apps.

Implementation of the API versioning in .Net core:

Before starting the implementation, there are 3 ways to handle the API versions:

1. Version in the URL

2. Version in the Headers

3. Query string Params

Create an application based on the .Net core platform and then add the Controller Method, To test this I have created the below one.

Install the below package from the Nuget manager.

Now make the changes in the startup/program.cs file in order to configure the services and use them.

builder.Services.AddApiVersioning(options => {
options.ReportApiVersions = true;
options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;

});

Now test this API and run it in Postman, In the next step we annotate the controller in order to apply the versions.

  1. Using URL version :

[Route("v{version:apiVersion}/products")]

Annotate the controller with the Route property and modify the Postman Url with the version in it.

if you change the version which is not implemented, then it will throw the error like the below one

localhost:7260/v2/products/all

Response :
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'localhost:7260/v2/products/all' does not support the API version '2'.",
"innerError": null
}
}

2. Header versioning

For this strategy, we need to modify the program.cs file like this :

builder.Services.AddApiVersioning(options => {
options.ReportApiVersions = true;
options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionReader = new HeaderApiVersionReader("X-API-Version");
});

Now include it under the API headers in Postman, and the controller class code changed like below, we have added versions 1.0 and 2.0 to the action method hence those only get supported, If we pass another version then the API will throw the unsupported version error message.

X-API-Version = 1

X-API-Version = 2

[Route("api/products")]
[ApiController]
public class ProductsController : Controller
{

[HttpGet("all")]
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public ActionResult ProductsList()
{
List products = new List();
products.Add("Mobiles");
products.Add("TV");
products.Add("Laptops");
return Ok(products);
}
}

3. Using Query string params:

In order to use the query string param version for the API, configure it in the program.cs file like the below : for this type versioning, used the default action method — Get() in order to test this strategy.

program.cs file

builder.Services.AddApiVersioning(options => {
options.ReportApiVersions = true;
options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionReader = new QueryStringApiVersionReader("prduct-version");
});

ProductsController.cs

[Route("api/products")]
[ApiController]
public class ProductsController : Controller
{
// GET: ProductsController

[HttpGet]
[ApiVersion("1.0")]
public IEnumerable Get()
{
List products = new List();
products.Add("Mobiles");
products.Add("TV");
products.Add("Laptops");
return products.Where(p => p != null);

}
}

query string named product-version is defined and it supports version 1.0 because the [Apiversion(“1.0”)] property was added to the action method hence its supports only that version other then that it will throw the unsupported version message.

Deprecating Previous Versions

If we want to deprecate the previous version without removing the code , just decorate the controller/action method like this :

[ApiVersion("2.0", Deprecated = true)]

Once the API is marked as deprecated hence the API response it will show the deprecated version.

while implementing the above example project, the inbuilt swagger will throw the error, to fix this add this code in the startup.cs file, for this, install the Versioning.API.Explorer package. This was added because our API was exposed to support the different types of versions in order to support this hence this service is configured.

builder.Services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});

builder.Services.AddEndpointsApiExplorer();

Hence, API versioning is a key practice for API Management.

Thank you for reading until the end. Please consider following the writer and this publication. Visit Stackademic to find out more about how we are democratizing free programming education around the world.

Did you find this article valuable?

Support Dileep Sreepathi by becoming a sponsor. Any amount is appreciated!