Skip to content

OData Protocol Transitions

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

One of the primary reasons to version a service is to facilitate changes in behavior and/or data exchange with the service. In the scope of OData, this can mean transitioning new versions of a service to use the OData protocol or it can mean existing OData services that are transitioning away from the OData protocol. The API versioning support for OData enables both of these scenarios.

The particulars and limitations of protocol transition only apply to ASP.NET Web API. The ASP.NET Core routing infrastructure is quite different and doesn't suffer from the same restrictions. Protocol transitions in ASP.NET Core, therefore, is as simple as implementing a standard controller and OData controller with the same route path.

Consider the following partial ASP.NET Web API controllers implementations:

[ApiVersion( 1.0 )]
public class OrdersController : ApiController
{
    public IHttpActionResult Get() => Ok();
}

[ApiVersion( 2.0 )]
[ControllerName( "Orders" )]
[ODataRoutePrefix( "Orders" )]
public class Orders2Controller : ODataController
{
    [ODataRoute]
    public IHttpActionResult Get() => Ok();
}

[ApiVersion( 3.0 )]
[ControllerName( "Orders" )]
public class Orders3Controller : ApiController
{
    public IHttpActionResult Get() => Ok();
}

This set of controllers produce the following semantics for the Orders service:

  • Version 1.0 of the service uses basic REST semantics and convention-based routing
  • Version 2.0 of the service switches to the OData protocol and convention-based routing
  • Version 3.0 of the service switches back to basic REST semantics and convention-based routing

Due to routing limitations in ASP.NET Web API, all versioned routes for a service must be either convention-based or attribute-based. Since OData relies on convention-based routing, all routes for a controller with the same name must also be convention-based in order for API versioning to function properly.

The configuration required to support this type of scenario will be:

config.AddApiVersioning();

var modelBuilder = new VersionedODataModelBuilder( config )
{
    ModelConfigurations = { new OrderModelConfiguration() }
};

config.MapVersionedODataRoutes( "odata", "api", modelBuilder );
config.Routes.MapHttpRoute( "orders", "api/{controller}/{id}", new { id = Optional } );

You can see a complete end-to-end implementation of this scenario in the advanced OData Web API sample.

Clone this wiki locally