ASP.NET Core › API Versioning

What is the difference between versioning at the API level (entire controller/group) versus versioning individual actions within a shared controller?

Intermediate

Answer

API-level versioning applies one or more [ApiVersion] attributes to the whole controller, meaning every action in it is available under all declared versions unless individually restricted. Action-level versioning uses [MapToApiVersion("x.0")] on specific actions within a multi-version controller to indicate that action only exists in that particular version, letting most actions be shared across versions while only the actually-changed ones are duplicated.
[ApiVersion("1.0")]
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/products")]
public class ProductsController : ControllerBase {
    [HttpGet]
    public IActionResult GetAll() => Ok(_products);  // available in both 1.0 and 2.0

    [HttpGet("{id}/reviews")]
    [MapToApiVersion("2.0")]
    public IActionResult GetReviews(int id) => Ok(_reviews);  // only in 2.0
}
Real-world example A products API adds a new reviews sub-resource only in v2 using MapToApiVersion, while the existing GetAll and GetById actions remain shared across both versions in the same controller, minimizing duplicated code.

Common follow-ups: What happens if MapToApiVersion references a version not declared on the controller?;When does splitting into fully separate controllers become clearer than this shared approach?