Skip to content

Version Interleaving

Chris Martinez edited this page Jul 28, 2016 · 6 revisions

API versions do not have to be split across different controller classes. A service author might choose to have a controller implement multiple API versions simultaneously. Controller actions can subsequently be mapped to specific API versions. This approach is useful for small version differences, but should be used sparingly to prevent developer confusion and complicate code maintenance. For example:

ASP.NET Web API

[ApiVersion( "2.0" )]
[ApiVersion( "3.0" )]
[RoutePrefix( "api/helloworld" )]
public class HelloWorld2Controller : ApiController
{
    [Route]
    public string Get() => "Hello world v2.0!";

    [Route, MapToApiVersion( "3.0" )]
    public string GetV3() => "Hello world v3.0!";
}

ASP.NET Web API and OData v4.0

[ApiVersion( "2.0" )]
[ApiVersion( "3.0" )]
[ControllerName( "People" )]
[ODataRoutePrefix( "People" )]
public class People2Controller : ODataController
{
    [ODataRoute]
    public IHttpActionResult Get( ODataQueryOptions<Person> options ) => Ok( new[]{ new Person() } );

    [ODataRoute, MapToApiVersion( "3.0" )]
    public IHttpActionResult GetV3( ODataQueryOptions<Person> options ) => Ok( new[]{ new Person() } );
}

ASP.NET Core

[ApiVersion( "2.0" )]
[ApiVersion( "3.0" )]
[Route( "api/helloworld" )]
public class HelloWorld2Controller : Controller
{
    [HttpGet]
    public string Get() => "Hello world v2.0!";

    [HttpGet, MapToApiVersion( "3.0" )]
    public string GetV3() => "Hello world v3.0!";
}

Although not illustrated in this example, it’s important to note that different versions of a service action might have different return values. The effect of the API versioning attribution is that the following requests match different controller and action implementations:

Request URL Matched Controller Matched Action
/api/helloworld?api-version=1.0 HelloWorldController Get
/api/helloworld?api-version=2.0 HelloWorld2Controller Get
/api/helloworld?api-version=3.0 HelloWorld2Controller GetV3
/api/People?api-version=1.0 PeopleController Get
/api/People?api-version=2.0 People2Controller Get
/api/People?api-version=3.0 People2Controller GetV3

It should be reiterated that the defined API version, even for an action, never directly influences routing. When the action matched for a route is ambiguous, the selection process will look for an explicit API version that matches the requested API version. If an explicit match is not found, then the action will be implicitly matched. If two actions are ambiguous by route and API version, then this is a developer mistake and the default behavior is unchanged.

Clone this wiki locally