I have a situation where I'm adding version control to an API, so the routes to some API functions change. I also changed some methods from POST to GET because it made more sense.
I'd like to deprecate the old routes so people start using the new ones. I want the old routes to be bound to v1 of my API and the new ones to be v2. I got this working by duplicating all functions and tagging them with the right route, method and api version, but I was hoping for a cleaner solution.
My 'cleaner' example below obviously doesn't work since you get 4 functions in this case, which are all deprecated.
You get:
/// <summary>
/// Gets a list of all channels
/// </summary>
/// <returns>List of all channels</returns>
[HttpPost, Route("~/channels"), ApiVersion("1.0"), Obsolete("Obsolete, please use /api/v2/channels/get")]
[HttpGet, Route("Get"), ApiVersion("2.0")]
public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannels()
{
return await _context.Monitors.ToListAsync();
}
Is there any way I can get this to work?
You could make two separate functions that act as "access points" to the internal logic of the API. One of them could be marked as Obsolete and use the old routes and the other would use the new routes. Then you could create a third function that contains the actual logic of your API.
// The obsolete access point
[HttpPost, Obsolete("Obsolete, please use /api/v2/channels/get"), ApiVersion("1.0")]
public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannelsOld()
{
return await GetChannelsLogic();
}
// The new access point
[HttpGet, ApiVersion("2.0")]
public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannelsNew()
{
return await GetChannelsLogic();
}
//Marked as NonAction so the method can't be accessed by a request. This is not necessary depending on the setup of your project.
[NonAction]
public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannelsLogic()
{
// Perform some other logic
return await _context.Monitors.ToListAsync();
}
Try to use
[HttpPost("~/channels"), ApiVersion("1.0"), Obsolete("Obsolete, please use /api/v2/channels/get")]
[HttpGet("Get"), ApiVersion("2.0")]
public async Task<ActionResult<IEnumerable<string>>> GetChannels()
{
return new List<string>();
}
so that you can only have two routes