Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

AV0019: An API cannot be versioned and version-neutral at the same time

Value
Rule IDAV0019
CategoryUsage
Fix isBreaking

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.