AV0019: An API cannot be versioned and version-neutral at the same time
| Value | |
|---|---|
| Rule ID | AV0019 |
| Category | Usage |
| Fix is | Breaking |
Cause
An API is declared both versioned and version-neutral.
Rule Description
Versioning metadata is inherited from a controller or an endpoint group as a convenience, and an action may state something more explicit in its place. Neutrality is the exception. It applies to the whole API, and an action cannot meaningfully claim a version of an API that has none.
Consider the following code:
[ApiController]
[ApiVersionNeutral]
[Route( "[controller]" )]
public class ExampleController : ControllerBase
{
[HttpGet]
[ApiVersion( 2.0 )]
public IActionResult Get() => Ok();
}
The controller states that the API has no versions while the action claims one of them.
The same conflict occurs with minimal APIs when a version is declared under a neutral group, or when both are declared together at the same level:
var orders = app.MapGroup( "/order" ).IsApiVersionNeutral();
orders.MapGet( "/", () => Results.Ok() ).HasApiVersion( 2.0 );
Controllers are collated by logical name, so a neutral declaration on one controller can silence versions declared on another that collates alongside it:
[ApiController]
[ApiVersionNeutral]
[Route( "example" )]
public class Example2Controller : ControllerBase { }
[ApiController]
[ApiVersion( 3.0 )]
[Route( "example" )]
public class Example3Controller : ControllerBase { }
How to Fix Violations
Decide whether the API is versioned or neutral and declare only that.
[ApiController]
[ApiVersion( 2.0 )]
[Route( "[controller]" )]
public class ExampleController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok();
}
When to Suppress Warnings
It is never safe to suppress this rule. The two declarations contradict each other and one of them will not be honored.