• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

206
Views
API versioning without duplicate code in C#

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:

  1. HTTPGET /channels
  2. HTTPPOST /channels
  3. HTTPGET /api/v2/channels/get
  4. HTTPPOST /api/v2/channels/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?

over 3 years ago · Santiago Trujillo
2 answers
Answer question

0

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();
    }
over 3 years ago · Santiago Trujillo Report

0

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

  1. HTTPPOST /channels
  2. HTTPGET /api/v2/channels/get
over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error