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

AV0015: Use a specific API version reader

Value
Rule IDAV0015
CategoryPerformance
Fix isBreaking

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.