Skip to content

How to Version Your Service

Chris Martinez edited this page Dec 29, 2022 · 11 revisions

REST services are implemented in ASP.NET as an endpoint. To version your service, you simply need to decorate your endpoints with the appropriate API version information. The method of decoration will vary depending on whether you are using controllers or Minimal APIs as well as whether you want to use attributes or conventions.

How It Works

The way that you create and define routes remains unchanged. The key difference is that routes may now overlap depending on whether you are using convention-based routing, attribute-based routing, or both. In the case of attribute routing, multiple controllers will define the same route. The default services in each flavor of ASP.NET assumes a one-to-one mapping between routes and endpoints and, therefore, considers duplicate routes to be ambiguous. The API versioning services replace the default implementations and allow endpoints to also be disambiguated by API version. Although multiple routes may match a request, they are expected to be distinguishable by API version. If the routes cannot be disambiguated, this is likely a developer mistake and the behavior is the same as the default implementation.

Supported Routing Methods

The following table outlines the various supported routing methods:

Routing Method Supported
Attribute-based routing Yes
Convention-based routing Yes
Attribute and convention-based routing (mixed) Yes*

* Due to limitations in the routing infrastructure in ASP.NET Web API, API versioning is not guaranteed to work for controllers that define both attribute and convention-based routes for the same route

Naming and Collation

While it might seem more intuitive that similar route templates are collated together, that is simply not the case. Consider that order/{id} and order/{id:int} are different, but semantically identical. API Versioning makes no attempt understand this difference. Although it is possible to have an API with a single endpoint, most APIs consist of a collection of endpoints; for example the Orders API. What if we saw the route template order/{id}/items? Is this part of the Orders API or some other API? For this reason, API Versioning collates on the logical name of an API and not individual route templates. For more information see: Controller Conventions.

Minimal APIs

Minimal APIs do not use controllers nor any of these conventions or attributes. The intrinsic grouping capabilities define collation without having to infer anything. It is, however, possible to add a logical API name to the group if you want to:

var builder = WebApplication.CreateBuilder( args );

builder.Services.AddProblemDetails();
builder.Services.AddApiVersioning();

var app = builder.Build();
var people = app.NewVersionedApi( "People" ); // ← provides optional, logical name

people.MapGet( "/people", () => new[] { new Person() } ).HasApiVersion( 1.0 );

app.Run();

Supported API Versioning Methods

Several API versioning methods are supported out-of-the-box:

Multiple methods of API versioning can be supported simultaneously. Use the ApiVersionReader.Combine method to compose two or more IApiVersionReader instances together. You can also implement your own method of extracting the requested API version using a custom IApiVersionReader.

Clone this wiki locally