Comprehensive Guide to API Versioning in .NET 8

Implementing API Versioning in .NET 8 with Evolving Models

What if you want to create a robust API and need to manage different versions to ensure backward compatibility, especially when models evolve over time? The default .NET application …


This content originally appeared on DEV Community and was authored by Roel

Implementing API Versioning in .NET 8 with Evolving Models

What if you want to create a robust API and need to manage different versions to ensure backward compatibility, especially when models evolve over time? The default .NET application template doesn’t provide this out of the box, so here's a guide to make this process simpler.

Requirements

  • .NET 8 Web API project
  • The following packages:
<ItemGroup>
    <PackageReference Include="Asp.Versioning.Http" Version="8.0.0" />
    <PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.0.0" />
</ItemGroup>

Guide

Follow these steps to implement versioning in your .NET 8 Web API project, including handling evolving models.

  1. Add the references above to the project

  2. Configure Services in Program.cs:

   var builder = WebApplication.CreateBuilder(args);

   builder.Services.AddApiVersioning(options =>
   {
       options.DefaultApiVersion = new ApiVersion(1, 0);
       options.AssumeDefaultVersionWhenUnspecified = true;
       options.ReportApiVersions = true;
       options.ApiVersionReader = ApiVersionReader.Combine(
           new UrlSegmentApiVersionReader(),
           new HeaderApiVersionReader("X-Api-Version")
       );
   }).AddApiExplorer(options =>
   {
       options.GroupNameFormat = "'v'VVV";
       options.SubstituteApiVersionInUrl = true;
   });

   builder.Services.AddControllers();
   builder.Services.AddEndpointsApiExplorer();
   builder.Services.AddSwaggerGen(c =>
   {
       c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API - V1", Version = "v1.0" });
       c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API - V2", Version = "v2.0" });
   });

   var app = builder.Build();

   if (app.Environment.IsDevelopment())
   {
       app.UseSwagger();
       app.UseSwaggerUI();
   }

   app.UseHttpsRedirection();
   app.UseAuthorization();
   app.MapControllers();
   app.Run();
  1. Implement Versioned Controllers: Create versioned controllers by decorating them with the ApiVersion attribute:
   namespace MyApp.Controllers.v1
   {
       [ApiVersion("1.0")]
       [Route("api/v{version:apiVersion}/[controller]")]
       [ApiController]
       public class WorkoutsController : ControllerBase
       {
           [MapToApiVersion("1.0")]
           [HttpGet("{id}")]
           public IActionResult GetV1(int id)
           {
               return Ok(new { Message = "This is version 1.0" });
           }
       }
   }

   namespace MyApp.Controllers.v2
   {
       [ApiVersion("2.0")]
       [Route("api/v{version:apiVersion}/[controller]")]
       [ApiController]
       public class WorkoutsController : ControllerBase
       {
           [MapToApiVersion("2.0")]
           [HttpGet("{id}")]
           public IActionResult GetV2(int id)
           {
               return Ok(new { Message = "This is version 2.0", NewField = "New data" });
           }
       }
   }
  1. Handling Evolving Models: When models evolve, create separate model classes for each version to maintain backward compatibility.

Version 1 Model:

   public class WorkoutV1
   {
       public int Id { get; set; }
       public string Name { get; set; }
   }

Version 2 Model with Additional Fields:

   public class WorkoutV2
   {
       public int Id { get; set; }
       public string Name { get; set; }
       public string Description { get; set; }  // New field
   }

Update the controller methods to use the appropriate models:

   namespace MyApp.Controllers.v1
   {
       [ApiVersion("1.0")]
       [Route("api/v{version:apiVersion}/[controller]")]
       [ApiController]
       public class WorkoutsController : ControllerBase
       {
           [MapToApiVersion("1.0")]
           [HttpGet("{id}")]
           public IActionResult GetV1(int id)
           {
               var workout = new WorkoutV1 { Id = id, Name = "Workout V1" };
               return Ok(workout);
           }
       }
   }

   namespace MyApp.Controllers.v2
   {
       [ApiVersion("2.0")]
       [Route("api/v{version:apiVersion}/[controller]")]
       [ApiController]
       public class WorkoutsController : ControllerBase
       {
           [MapToApiVersion("2.0")]
           [HttpGet("{id}")]
           public IActionResult GetV2(int id)
           {
               var workout = new WorkoutV2 { Id = id, Name = "Workout V2", Description = "This is a description." };
               return Ok(workout);
           }
       }
   }
  1. Configure Swagger Documentation: Ensure each API version has its own Swagger documentation:
   builder.Services.AddSwaggerGen(c =>
   {
       c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API - V1", Version = "v1.0" });
       c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API - V2", Version = "v2.0" });
   });
  1. Run Your Application: Build and run your application to see the versioned API in action:
   dotnet run
  1. Access Different API Versions: Use the URL to access different versions of your API:
    • Version 1.0: https://localhost:5001/api/v1/workouts/{id}
    • Version 2.0: https://localhost:5001/api/v2/workouts/{id}

Deprecating API Versions

To deprecate an old API version, set the Deprecated property on the ApiVersion attribute:

[ApiVersion("1.0", Deprecated = true)]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class DeprecatedController : ControllerBase
{
    [HttpGet("{id}")]
    public IActionResult GetV1(int id)
    {
        return Ok(new { Message = "This version is deprecated." });
    }
}

Organizing Versioned Controllers and Models in Solution Explorer

To keep your project organized, especially as you add more versions, follow these tips:

  1. Create a Folder Structure:
    • Create a main folder called Controllers and subfolders for each version, e.g., v1, v2.
    • Place each version of your controllers in the respective folder.

Example structure:

   - Controllers
     - v1
       - WorkoutsController.cs
     - v2
       - WorkoutsController.cs
   - Models
     - v1
       - WorkoutV1.cs
     - v2
       - WorkoutV2.cs
  1. Naming Conventions:

    • Use clear and consistent naming conventions to differentiate between versions.
    • Include the version number in the model and controller class names if needed for clarity, e.g., WorkoutV1, WorkoutV2.
  2. Updating Namespaces:

    • Ensure the namespaces reflect the folder structure to avoid conflicts.
    • Example:
     namespace MyApp.Models.v1
     {
         public class WorkoutV1
         {
             public int Id { get; set; }
             public string Name { get; set; }
         }
     }
    
     namespace MyApp.Models.v2
     {
         public class WorkoutV2
         {
             public int Id { get; set; }
             public string Name { get; set; }
             public string Description { get; set; }  // New field
         }
     }
    
  3. Consistent Routing:

    • Ensure your routing attributes are consistent and clear to indicate the version in the URL path.

All Done!

Now you have a versioned API that can evolve smoothly while maintaining backward compatibility. Don’t forget to document and communicate breaking or big changes! Feel free to experiment and make it even more advanced!


This content originally appeared on DEV Community and was authored by Roel


Print Share Comment Cite Upload Translate Updates
APA

Roel | Sciencx (2024-06-29T22:11:44+00:00) Comprehensive Guide to API Versioning in .NET 8. Retrieved from https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/

MLA
" » Comprehensive Guide to API Versioning in .NET 8." Roel | Sciencx - Saturday June 29, 2024, https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/
HARVARD
Roel | Sciencx Saturday June 29, 2024 » Comprehensive Guide to API Versioning in .NET 8., viewed ,<https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/>
VANCOUVER
Roel | Sciencx - » Comprehensive Guide to API Versioning in .NET 8. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/
CHICAGO
" » Comprehensive Guide to API Versioning in .NET 8." Roel | Sciencx - Accessed . https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/
IEEE
" » Comprehensive Guide to API Versioning in .NET 8." Roel | Sciencx [Online]. Available: https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/. [Accessed: ]
rf:citation
» Comprehensive Guide to API Versioning in .NET 8 | Roel | Sciencx | https://www.scien.cx/2024/06/29/comprehensive-guide-to-api-versioning-in-net-8/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.