AV0015: Use a specific API version reader
| Value | |
|---|---|
| Rule ID | AV0015 |
| Category | Performance |
| Fix is | Breaking |
Cause
An API reads its version one way, but the reader was left to accept more than one.
Rule Description
Without an explicit reader, an API version is looked for in both the query string and the URL segment. Every route in the application is examined to decide which of the two is actually used. When they all agree, the other reader is asked for a version on every request and never finds one.
Consider the following code:
var builder = WebApplication.CreateBuilder( args );
builder.Services.AddApiVersioning();
var app = builder.Build();
app.MapGet( "/v{version:apiVersion}/order", () => Results.Ok() ).HasApiVersion( 1.0 );
app.MapGet( "/v{version:apiVersion}/customer", () => Results.Ok() ).HasApiVersion( 1.0 );
app.Run();
Every route carries the API version constraint, so the version is only ever read from the URL segment. The query string is searched on every request for a value that is never there.
Any mixture of the two styles, or a route that cannot be followed back to its origin, leaves the default in place and is not reported; narrowing the reader would then break a form the application relies on.
How to Fix Violations
Configure the reader the application actually uses.
builder.Services.AddApiVersioning(
options =>
{
options.ApiVersionReader = new UrlSegmentApiVersionReader();
} );
An application whose routes never carry the constraint reads its version from the query string instead:
builder.Services.AddApiVersioning(
options =>
{
options.ApiVersionReader = new QueryStringApiVersionReader();
} );
When to Suppress Warnings
It is safe to suppress this rule if the additional reader is intended; for example, when the routes visible to the compiler are only part of the application, or when a client is knowingly allowed to name a version either way. Configuring a specific reader stops the other form from being accepted, so applying the fix to an existing service is a breaking change for any client using it.