Introduction
As APIs evolve, new features are added, existing endpoints change, and outdated functionality is eventually removed. Without a proper versioning strategy, these changes can break existing client applications and create maintenance challenges.
API versioning allows you to introduce changes while maintaining backward compatibility for consumers using older versions of your API. ASP.NET Core provides flexible options for implementing API versioning, making it easier to manage multiple API versions within the same application.
In this article, you'll learn why API versioning is important, explore the most common versioning strategies, and discover best practices for building maintainable and scalable ASP.NET Core APIs.
What Is API Versioning?
API versioning is the practice of maintaining multiple versions of an API so that existing clients continue to function while new clients can take advantage of updated features.
Instead of modifying an existing endpoint directly, you introduce a new version.
For example:
/api/v1/products
/api/v2/products
Both versions can exist simultaneously, allowing applications to migrate at their own pace.
Why API Versioning Matters
Without versioning, even small API changes can impact existing consumers.
Benefits of API versioning include:
Maintains backward compatibility
Supports gradual feature rollout
Reduces breaking changes
Simplifies API maintenance
Improves developer experience
Enables safer application updates
A well-planned versioning strategy also helps teams evolve APIs without disrupting production systems.
Common API Versioning Strategies
There are several ways to version an API.
URL Versioning
The version is included in the request URL.
Example:
/api/v1/orders
/api/v2/orders
Advantages
Easy to understand
Simple to document
Widely adopted
Easy to test
This is the most commonly used approach for public REST APIs.
Query String Versioning
The version is passed as a query parameter.
Example:
/api/orders?api-version=1.0
This approach keeps URLs consistent but is less common for public APIs.
Header Versioning
The client specifies the version using an HTTP header.
Example:
api-version: 2.0
This keeps URLs clean but requires clients to configure request headers.
Media Type Versioning
The version is specified in the Accept header.
Example:
Accept: application/json;version=2.0
This approach follows REST principles but is more complex to implement and consume.
Installing API Versioning
Add the required NuGet package to your ASP.NET Core project.
dotnet add package Asp.Versioning.Mvc
Once installed, configure versioning during application startup.
Configure API Versioning
Register API versioning in Program.cs.
using Asp.Versioning;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
});
var app = builder.Build();
app.MapControllers();
app.Run();
This configuration sets a default version and includes supported API versions in response headers.
Creating Versioned Controllers
You can define different versions of the same controller using attributes.
Version 1:
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/products")]
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok("Products from API V1");
}
}
Version 2:
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/products")]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok("Products from API V2");
}
}
Clients can now choose the appropriate version based on their requirements.
Supporting Multiple Versions
Sometimes an endpoint remains unchanged across multiple versions.
ASP.NET Core allows a single controller to support more than one version.
[ApiVersion("1.0")]
[ApiVersion("2.0")]
This avoids unnecessary code duplication while supporting multiple API versions.
Deprecating Older Versions
Eventually, older API versions should be retired.
Mark an API version as deprecated.
[ApiVersion("1.0", Deprecated = true)]
This informs API consumers that they should migrate to a newer version.
Deprecation notices should also be documented clearly to provide clients with sufficient time to update.
Versioning and Swagger
If you're using Swagger (OpenAPI), configure it to display separate documentation for each API version.
Benefits include:
Providing version-specific documentation helps consumers understand the differences between releases.
Best Practices for API Versioning
Follow these recommendations when designing versioned APIs:
Choose a versioning strategy before releasing your API.
Prefer URL versioning for public REST APIs due to its simplicity.
Avoid unnecessary breaking changes.
Keep older versions available until consumers have migrated.
Document version differences clearly.
Deprecate APIs gradually rather than removing them immediately.
Use semantic version numbers where appropriate.
Maintain consistent naming conventions across versions.
These practices make your APIs easier to maintain and consume.
Common Mistakes to Avoid
Many teams encounter problems because of poor versioning practices.
Avoid these common mistakes:
Releasing breaking changes without increasing the API version.
Supporting too many outdated versions indefinitely.
Mixing multiple versioning strategies in the same API.
Failing to document deprecated endpoints.
Changing response formats without introducing a new version.
Ignoring backward compatibility during development.
A clear versioning policy helps prevent confusion for both developers and API consumers.
When Should You Create a New API Version?
Not every change requires a new version.
A new version is typically needed when you:
Remove existing properties.
Change response formats.
Modify endpoint behavior.
Rename endpoints.
Introduce breaking authentication changes.
Minor enhancements, such as adding optional fields or new endpoints, can often be introduced without creating a new API version, provided they don't break existing clients.
Conclusion
API versioning is an essential part of building reliable and maintainable ASP.NET Core applications. It enables teams to evolve their APIs while preserving compatibility for existing consumers, reducing the risk of breaking changes.
Whether you choose URL, query string, header, or media type versioning, consistency is the key to long-term success. By planning your versioning strategy early, documenting changes clearly, and deprecating older versions responsibly, you can deliver APIs that are easier to maintain, simpler to consume, and ready to support future enhancements.