Implementing API Versioning in .NET Core

API versioning is a critical concept in software development, especially when building RESTful APIs. It ensures backward compatibility while allowing the introduction of new features, changes, or improvements. In this article, we’ll explore how to implement API versioning in a .NET Core Web API, including detailed examples and explanations.


What is API Versioning?

API versioning is the practice of managing changes to an API while ensuring that existing clients can continue to use the previous versions. This allows you to:

  • Add new functionality without breaking existing clients.
  • Deprecate old features gradually.
  • Ensure a smooth transition for consumers of your API.

Why Use API Versioning?

  1. Backward Compatibility: It ensures existing applications that rely on older versions of your API continue to function without issues.
  2. Incremental Changes: Allows for iterative improvements and feature additions.
  3. Consumer Flexibility: Consumers can choose when to upgrade to a newer version, avoiding forced migrations.

Versioning Strategies

Here are the most common API versioning strategies:

  1. URL Path Versioning: Embed the version number in the URL path (e.g., /api/v1/values).
  2. Query String Versioning: Include the version number as a query parameter (e.g., /api/values?version=1).
  3. Header Versioning: Specify the version number in a custom header (e.g., X-Version: 1).
  4. Media Type Versioning: Use custom media types in the Accept header (e.g., application/vnd.myapi.v1+json).

In .NET Core, the Microsoft.AspNetCore.Mvc.Versioning package simplifies the implementation of these strategies.


Setting Up API Versioning in .NET Core Web API

Step 1: Install the NuGet Package

To enable API versioning, install the Microsoft.AspNetCore.Mvc.Versioning package:

dotnet add package Microsoft.AspNetCore.Mvc.Versioning


Step 2: Configure API Versioning

Modify the Program.cs or Startup.cs file to configure API versioning.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Versioning;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

// Configure API versioning
builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0); // Default API version
    options.AssumeDefaultVersionWhenUnspecified = true; // Assume default when version is not specified
    options.ReportApiVersions = true; // Adds headers for supported versions
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Key Configuration Options:

  1. DefaultApiVersion: Sets the default version when none is specified.
  2. AssumeDefaultVersionWhenUnspecified: Allows the default version to be assumed when no version is explicitly provided.
  3. ReportApiVersions: Adds headers to the response indicating supported API versions.

Step 3: Create Versioned Controllers

Version 1

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new { Version = "1.0", Message = "This is version 1.0" });
    }
}

Version 2

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new { Version = "2.0", Message = "This is version 2.0" });
    }
}


Step 4: Test the API

  1. Version 1 Request: GET https://localhost:5001/api/v1/values Response: { "version": "1.0", "message": "This is version 1.0" }
  2. Version 2 Request: GET https://localhost:5001/api/v2/values Response: { "version": "2.0", "message": "This is version 2.0" }

Alternative Versioning Strategies

1. Query String Versioning

To use query string versioning, update the configuration:

builder.Services.AddApiVersioning(options =>
{
    options.ApiVersionReader = new QueryStringApiVersionReader("version");
});

Request Example:

GET https://localhost:5001/api/values?version=1.0


2. Header Versioning

For header-based versioning:

builder.Services.AddApiVersioning(options =>
{
    options.ApiVersionReader = new HeaderApiVersionReader("X-Version");
});

Request Example:

GET https://localhost:5001/api/values
X-Version: 1.0


3. Media Type Versioning

For media type versioning:

builder.Services.AddApiVersioning(options =>
{
    options.ApiVersionReader = new MediaTypeApiVersionReader();
});

Request Example:

GET https://localhost:5001/api/values
Accept: application/vnd.myapi.v1+json


Advanced Features

API Versioning Conventions

Instead of annotating each controller with [ApiVersion], you can use conventions:

builder.Services.AddApiVersioning(options =>
{
    options.Conventions.Controller<ValuesController>()
        .HasApiVersion(1, 0)
        .HasApiVersion(2, 0);
});

Deprecating API Versions

Deprecate a version by setting the IsDeprecated property:

[ApiVersion("1.0", Deprecated = true)]


Best Practices for API Versioning

  1. Plan for Versioning Early: Introduce versioning from the start to avoid breaking changes.
  2. Document Supported Versions: Clearly document which versions are supported and any deprecated ones.
  3. Use Semantic Versioning: Align your API versions with semantic versioning principles (e.g., 1.0, 2.0).
  4. Deprecation Policy: Define a clear policy for deprecating old API versions.

Conclusion

API versioning is an essential aspect of maintaining a scalable and user-friendly API. .NET Core makes it easy to implement and manage versioning with the Microsoft.AspNetCore.Mvc.Versioning package. By choosing the right versioning strategy and adhering to best practices, you can ensure a smooth experience for both developers and consumers.

By following the examples and configurations provided in this guide, you should be well-equipped to implement API versioning in your .NET Core Web API projects.

By:


Leave a comment