Description
Background and Motivation
Minimal APIs and MVC controller can define versioned routes, which typically use the same route template.
ASP0022
will fire for the following Minimal APIs:
var forecast = app.NewVersionedApi();
var v1 = forecast.MapGroup("/weatherforecast");
var v2 = forecast.MapGroup("/weatherforecast");
v1.MapGet("/", () => [new WeatherForecastV1()]).HasApiVersion(1.0);
v2.MapGet("/", () => [new WeatherForecastV2()]).HasApiVersion(2.0);
ASP0023
will fire for the following controllers:
namespace My.Api.Controllers.V1
{
[ApiVersion(1.0)]
[Route("[controller]")]
public sealed class WeatherForecast : ControllerBase
{
[HttpGet]
public WeatherForecastV1[] Get() => Ok([new WeatherForecastV1()]);
}
}
namespace My.Api.Controllers.V2
{
[ApiVersion(2.0)]
[Route("[controller]")]
public sealed class WeatherForecast : ControllerBase
{
[HttpGet]
public WeatherForecastV2[] Get() => Ok([new WeatherForecastV2()]);
}
}
- Enabled by default
- Indicate that these rules should not be suppressed
These routes are not ambiguous and will not result in a runtime error. The lack of extensibility or knowledge of this capability, reports false positives and instructs users not to suppress these warnings. That is confusing to users. While it is possible for library authors to suppress this warning, that is unintuitive to users and there is still a scenario where the route pattern with its metadata is ambiguous and will produce a runtime error.
Proposed Analyzer
The analyzers for ASP0022
and ASP0023
should provide one or more of the following:
- Be API version-aware
- Allow/surface route-disambiguation metadata
- Allow analyzer extensibility (to be defined)
Analyzer Behavior and Message
In the examples above, ASP0022
and ASP0023
should not produce any warnings. The rules should, however, still be produced in the following scenarios:
ASP0022
should fire for the following Minimal APIs:
var forecast = app.NewVersionedApi();
var v1 = forecast.MapGroup("/weatherforecast");
var v2 = forecast.MapGroup("/weatherforecast");
v1.MapGet("/", () => [new WeatherForecastV1()]).HasApiVersion(1.0);
v2.MapGet("/", () => [new WeatherForecastV2()]).HasApiVersion(1.0); // ← duplicate route + version
ASP0023
should fire for the following controllers:
namespace My.Api.Controllers.V1
{
[ApiVersion(1.0)]
[Route("[controller]")]
public sealed class WeatherForecast : ControllerBase
{
[HttpGet]
public WeatherForecastV1[] Get() => Ok([new WeatherForecastV1()]);
}
}
namespace My.Api.Controllers.V2
{
[ApiVersion(1.0)] // ← duplicate route + version
[Route("[controller]")]
public sealed class WeatherForecast : ControllerBase
{
[HttpGet]
public WeatherForecastV2[] Get() => Ok([new WeatherForecastV2()]);
}
}
Category
- Design
- Documentation
- Globalization
- Interoperability
- Maintainability
- Naming
- Performance
- Reliability
- Security
- Style
- Usage
Severity Level
- Error
- Warning
- Info
- Hidden
Usage Scenarios
Any developer using ASP.NET Core with API Versioning is likely to encounter false positive warnings that they must either ignore or suppress. Users should be able to version their APIs, while still having the benefit of detecting duplicate routes.
Risks
- Suppressing these rules for versioned routes can still result in ambiguous routes, which is what the analysis rules were meant to solve