A comprehensive demonstration of API versioning in ASP.NET Core using URL path versioning with Swagger documentation.
- URL Path Versioning: Clean versioning using URL segments (e.g.,
/api/v1.0/Hello,/api/v2.0/Hello) - Swagger Integration: Interactive API documentation with version-specific endpoints
- Version Discovery: Automatic API version reporting in response headers
- Deprecation Support: Mark older API versions as deprecated
- Multiple Controllers: Separate controllers for different API versions
- Clean Architecture: Well-organized project structure
- .NET 9.0: Latest .NET framework
- ASP.NET Core: Web API framework
- Microsoft.AspNetCore.Mvc.Versioning: API versioning library
- Swashbuckle.AspNetCore: Swagger/OpenAPI documentation
- Microsoft.AspNetCore.OpenApi: OpenAPI specification support
- .NET 9.0 SDK
- Visual Studio Code, Visual Studio, or any preferred IDE
- Git (for cloning the repository)
git clone https://github.com/mphiliseni/API-Versioning-.git
cd API-Versioning-/APIVersiondotnet restoredotnet builddotnet runThe API will be available at https://localhost:5238 (or the port shown in the console output).
- GET
/api/v1.0/Hello- Returns greeting from version 1.0 - Response:
"π Hello API - Version 1"
- GET
/api/v2.0/Hello- Returns greeting from version 2.0 - Response:
"π Hello API - Version 2"
- Swagger UI:
/swagger- Interactive API documentation - OpenAPI Spec:
/swagger/{version}/swagger.json- OpenAPI specification for each version
The API versioning is configured in Program.cs:
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
}).AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});Controllers are versioned using attributes:
[ApiVersion("1.0", Deprecated = true)] // V1 - Deprecated
[ApiVersion("2.0")] // V2 - Current
[Route("api/v{version:apiVersion}/[controller]")]APIVersion/
βββ Controllers/
β βββ V1/
β β βββ HelloController.cs # Version 1.0 controller (deprecated)
β βββ V2/
β βββ HelloController.cs # Version 2.0 controller
βββ Options/
β βββ ConfigureSwaggerOptions.cs # Swagger configuration
βββ Properties/
β βββ launchSettings.json # Launch configuration
βββ Program.cs # Application startup
βββ ApiVersion.csproj # Project file
βββ appsettings.json # Application settings
# Test Version 1.0
curl -X GET "https://localhost:5238/api/v1.0/Hello"
# Test Version 2.0
curl -X GET "https://localhost:5238/api/v2.0/Hello"
# Check API versions (look for api-supported-versions header)
curl -I "https://localhost:5238/api/v2.0/Hello"- Navigate to
https://localhost:5238/swagger - Select the API version from the dropdown
- Expand the endpoint and click "Try it out"
- Execute the request to see the response
The API reports supported versions in the api-supported-versions response header, making it easy for clients to discover available versions.
Version 1.0 is marked as deprecated using the Deprecated = true parameter, which will be reflected in the API documentation and response headers.
This implementation uses URL path versioning (/api/v{version}/controller), which is:
- SEO Friendly: Easy to cache and index
- Clear: Version is explicitly visible in the URL
- Routing Friendly: Works well with ASP.NET Core routing
Each API version gets its own Swagger document, allowing for:
- Version-specific documentation
- Different schemas per version
- Clear separation of concerns
dotnet run --environment Developmentdotnet publish -c Release -o ./publish- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- ASP.NET Core API Versioning Documentation
- Microsoft Docs: API Versioning
- Swagger/OpenAPI Documentation
If you get a "port already in use" error:
# Find the process using the port
lsof -i :5238
# Kill the process (replace PID with actual process ID)
kill -9 <PID>Ensure all NuGet packages are restored:
dotnet clean
dotnet restore
dotnet buildMade with β€οΈ using ASP.NET Core and API Versioning