-
Notifications
You must be signed in to change notification settings - Fork 709
Versioning by Media Type
Content negotiation is the defined method in REST for reasoning about the content expectations between a client and server. The parameters used in media types for content negotiation can contain custom input that can be used to drive API versioning.
Let's assume the following controllers are defined:
namespace Services.V1
{
[ApiVersion( "1.0" )]
[RoutePrefix( "api/helloworld" )]
public class HelloWorldController : ApiController
{
[Route]
public string Get() => "Hello world!";
}
}
namespace Services.V2
{
[ApiVersion( "2.0" )]
[RoutePrefix( "api/helloworld" )]
public class HelloWorldController : ApiController
{
[Route]
public string Get() => "Hello world!";
[Route]
public string Post( string text ) => text;
}
}
namespace Services.V1
{
[ApiVersion( "1.0" )]
[ApiController]
[Route( "api/[controller]" )]
public class HelloWorldController : ControllerBase
{
[HttpGet]
public string Get() => "Hello world!";
}
}
namespace Services.V2
{
[ApiVersion( "2.0" )]
[ApiController]
[Route( "api/[controller]" )]
public class HelloWorldController : ControllerBase
{
[HttpGet]
public string Get() => "Hello world!";
[HttpPost]
public string Post( string text ) => text;
}
}
ASP.NET Web API and ASP.NET Core would then change the default API version reader as follows:
options => options.ApiVersionReader = new MediaTypeApiVersionReader();
The default behavior will require that clients always specify an API version, so service authors will likely want their configuration to be:
options =>
{
options.ApiVersionReader = new MediaTypeApiVersionReader();
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector( options );
}
This will allow clients to request a specific API version by media type, but if they don't specify anything, they will receive the current implementation (e.g. API version). For example:
GET api/helloworld HTTP/1.1
host: localhost
Figure 1: returns the result from API version 2.0 because it's the current version
GET api/helloworld HTTP/1.1
host: localhost
accept: text/plain;v=1.0
Figure 2: returns the result from API version 1.0
POST api/helloworld HTTP/1.1
host: localhost
content-type: text/plain;v=2.0
content-length: 12
Hello there!
Figure 3: explicitly posts the content to API version 2.0, even though it would be implicitly matched
Defining new, custom media types (ex: application/vnd.my.company.1+json
) to drive API versioning is another variant of this approach that is accepted within the constraints of REST. This method of API versioning, however, is not supported out-of-the-box. The primary rationale for this decision is driven by the amount of developer configuration. API versioning using custom media types requires more setup than just a few configuration settings. The service author must also register the custom media types with the ASP.NET platform so that it knows how to handle incoming requests. If this is the method of API versioning that you prefer, all of the necessary extension points are in place so that you can implement it, but it's not a capability that is provided for you.
- Home
- Quick Starts
- Version Format
- Version Discovery
- Version Policies
- How to Version Your Service
- API Versioning with OData
- Configuring Your Application
- Error Responses
- API Documentation
- Extensions and Customizations
- Known Limitations
- FAQ
- Examples