Hello All,
API Versioning is either something you love or you hate. But really It’s great for giving developers the ability to improve and iterate on API’s without breaking contracts.
We have created the API in the article Web API Part 1 - ASP .NET Core Web API Using EntityFrameworkCore and MSSQL Server as Database
Also added CORS to the API in Web API Part 2 - Adding CORS to ASP .NET Core Web API
So We will continue from second part and start working on Versioning.
What is happening?
When we create the service, it will be accessible from many clients. Business grows day by day, as well requirements are getting changed, in that case to achieve the business requirement there will be a change in Service also.
But our main intension is when we update the existing service, it should not break any existing client applications. We should design service like that, it should carry enhancement and existing features.
So, the answer is API Versioning....
This way we keep old service as it is, so none of the client get issue. For enhancement we create the new version of API that new client applications can start using.
As per my experience, versioning API is very important and it should be implemented in any API projects.
Types Of Versioning:
There are three types of versioning we have.
1. Query String Based
2. URL Based
3. Http Header Based Approach
1. Query String Based
This is the approach where we can specify the API version in the Query String.
For Example:
https://server.com/api/values?api-version=1.0
2. URL Based
Frankly speaking, I do not like query string based pattern. Its not looks good to send the API version as a query string as API contains other query strings like id of the data object.
URL based versioning is the best and clean approach.
We should decorate our controller or action method with Route attribute and it has version parameter. We will discuss this in detail.
[Route("api/{v:apiVersion}/values"]
For Example:
/api/v1/values
3. Http Header Based
Some clients or user does not want to change the URL of the API, Then we can send the version of the API in the form of Http Header.
To enable Http Header pattern we need to add the version reader under configureService method inside startup.cs but .Net 6 we will add in Program.cs
o.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
After this query string pattern will not work, if you need both then we need to add the below code
o.ApiVersionReader = new QueryStringOrHeaderApiVersionReader("x-api-version");
Once all the steps implemented then we can specify the API version in header part while calling the API
For Example:
GET : http://localhost:54373/api/values
Header(1)
api-version 1.0
--------------------------------------------------------------------------------------------------------------------------------------------------
That's it, these are the three types of version.
Now we will learn, Step by Step Query Based Versioning Pattern.
Lets begin.
First, We will download the source code from Web API Part 2 - Adding CORS to ASP .NET Core Web API
1. Open the above mentioned project in Visual Studio
- Microsoft.AspNetCore.Mvc.Versioning
builder.Services.AddApiVersioning(option => { option.DefaultApiVersion = new ApiVersion(1, 0); option.AssumeDefaultVersionWhenUnspecified = true; option.ReportApiVersions = true; });
content-type : application/json server : kestrel
It is used to set the default version when client has not specified any version. If we do not specify this then error will occur if no version specified.
Do not forget, when you test in Swagger:Swagger will through the error when you have two methods with same route, because swagger will think its conflict.We need to replace the swagger code in Program.cs with below codebuilder.Services.AddSwaggerGen(c =>{c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());});
https://localhost:7289/api/v1/Learning/learning-list
https://localhost:7289/api/v2/Learning/learning-list
[ApiController] [Route("api/v{version:apiVersion}/Learning")] [ApiVersion("1.0", Deprecated = true)] [ApiVersion("2.0")] [EnableCors("SampleCORS")] public class LearningController : ControllerBase {