'Rest APi How to route based api versioning
I have a method called GetMessage, it is called like so:
localhost/GetMessage?id={{NewMessage}}
i have now decided to start following standard practises and ommit the "get" keyword from the route and make it like so:
localhost/message?id={{NewMessage}}
however, i do not want to break any existing clients I already have looking at the first route and force them to update. the underlying function will not change, it will just be the route.
my first solution to this problem was to do this:
Although THIS WORKS i realised, i have like 35 functions just like this one, i do not wanna duplicate all those functions.
Is it not possible to add 2 [httpget] attributes to a function each with a different apiversion that would only be accessible if the header specifically has that version.
so something like this:
this way client will be able to upgrade in their own time when they need.
is this possible or would i have to go with my first solution?
Extra info:
my configure services method:
Solution 1:[1]
Generally , the method with different version has the same route, So we configure like this:
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
o.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
And user add request header(x-api-version=xxxx) to access method with the specified version
But in your code, Different versions of methods have different routes, So We can't use the method mentioned above.
I use Action filters to achieve a similar effect, I write a simple demo here.
Action filters
public class Action1filter : Attribute,IActionFilter
{
private readonly string _header;
private readonly string _value;
public void OnActionExecuted(ActionExecutedContext context){}
public void OnActionExecuting(ActionExecutingContext context )
{
if ((context.HttpContext.Request.Headers.FirstOrDefault(x => x.Key == _header).Value.FirstOrDefault() != _value) || context.HttpContext.Request.Headers.FirstOrDefault(x => x.Key == _header).Value.FirstOrDefault() == null)
{
context.Result= new BadRequestObjectResult("");
}
}
}
your method
HttpGet("message"), ApiVersion("2.0"), Action1filter("version", "2.0")]
public IActionResult GetMessage2([FromQuery] string Id)
{
return GetMessage(Id);
}
[HttpGet("GetMessage"),ApiVersion("1.0",Deprecated =true), Action1filter("version", "1.0")]
public IActionResult GetMessage([FromQuery]string Id)
{
return Ok(Id);
}
I add the ActionFilter in your action, So only the request with header version=2.0 can access the method by localhost/message?id={{NewMessage}}
But you can't use this method in your second solution, Because one [Action1filter()] will work on both paths.
In my opinion, I prefer to add [Route("xxx/{version:apiVersion}")] to access method with different versions in this situation
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |



