- Notifications
You must be signed in to change notification settings - Fork709
Versioning via the URL Path
An alternate, but common, method of API versioning is to use a URL path segment. This approach does not allow implicitly matching the initial, default API version of a service; therefore, all API versions must be explicitly declared. In addition, the API version value specified for the URL segment must still conform to theversion format. Thev
prefix isnot part of the API version, but may be included in route templates if you so desire.
Note: It is not possible to have a default API version for a URL path segment. This means that setting
ApiVersioningOptions.AssumedDefaultVersionWhenUnspecified
is unlikely to have any affect when you use this method of versioning. For more information and possible solutions to address this scenario, refer to theknown limitations.
publicstaticclassWebApiConfig{publicstaticvoidConfiguration(HttpConfigurationconfiguration){varconstraintResolver=newDefaultInlineConstraintResolver(){ConstraintMap={["apiVersion"]=typeof(ApiVersionRouteConstraint)}};configuration.MapHttpAttributeRoutes(constraintResolver);configuration.AddApiVersioning();}}
[ApiVersion(1.0)][Route("api/v{version:apiVersion}/helloworld")]publicclassHelloWorldController:ApiController{publicstringGet()=>"Hello world!";}[ApiVersion(2.0)][ApiVersion(3.0)][Route("api/v{version:apiVersion}/helloworld")]publicclassHelloWorld2Controller:ApiController{publicstringGet()=>"Hello world v2!";[MapToApiVersion(3.0)]publicstringGetV3()=>"Hello world v3!";}
Since the OData implementation uses convention-based routes under the hood, theApiVersionRouteConstraint
is automatically added to all versioned OData routes when needed. The name of the constraint used in prefixes of OData routes must beapiVersion
and cannot be changed.
publicstaticclassWebApiConfig{publicstaticvoidConfiguration(HttpConfigurationconfiguration){varmodelBuilder=newVersionedODataModelBuilder(configuration){ModelConfigurations={newPersonModelConfiguration()}};configuration.AddApiVersioning();configuration.MapVersionedODataRoutes("odata-bypath","api/v{apiVersion}",modelBuilder);}}
[ApiVersion(1.0)][ODataRoutePrefix("People")]publicclassPeopleController:ODataController{[EnableQuery][ODataRoute]publicIQueryable<Person>Get()=>new[]{newPerson()}.AsQueryable();}[ApiVersion(2.0)][ApiVersion(3.0)][ControllerName("People")][ODataRoutePrefix("People")]publicclassPeople2Controller:ODataController{[EnableQuery][ODataRoute]publicIQueryable<Person>Get()=>new[]{newPerson()}.AsQueryable();[EnableQuery][ODataRoute,MapToApiVersion(3.0)]publicIQueryable<Person>GetV3()=>new[]{newPerson()}.AsQueryable();}
[ApiVersion(1.0)][ApiController][Route("api/v{version:apiVersion}/[controller]")]publicclassHelloWorldController:ControllerBase{[HttpGet]publicstringGet()=>"Hello world!";}[ApiVersion(2.0)][ApiVersion(3.0)][ApiController][Route("api/v{version:apiVersion}/helloworld")]publicclassHelloWorld2Controller:ControllerBase{[HttpGet]publicstringGet()=>"Hello world v2!";[HttpGet,MapToApiVersion(3.0)]publicstringGetV3()=>"Hello world v3!";}
[ApiVersion(1.0)]publicclassPeopleController:ODataController{[EnableQuery]publicIQueryable<Person>Get()=>new[]{newPerson()}.AsQueryable();}[ApiVersion(2.0)][ApiVersion(3.0)][ControllerName("People")]publicclassPeople2Controller:ODataController{[EnableQuery][ODataRoute]publicIQueryable<Person>Get()=>new[]{newPerson()}.AsQueryable();[EnableQuery][ODataRoute,MapToApiVersion(3.0)]publicIQueryable<Person>GetV3()=>new[]{newPerson()}.AsQueryable();}
varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddControllers().AddOData();builder.Services.AddProblemDetails();builder.Services.AddApiVersioning().AddOData( options=>{options.ModelBuilder.DefaultModelConfiguration=(builder,apiVersion,routePrefix)=>{builder.EntitySet<Person>("People");};options.AddRouteComponents("api/v{version:apiVersion}");});varapp=builder.Build();app.MapControllers();app.Run();
The effect of the API version attribution is that the following requests match different controller implementations:
Request URL | Matched Controller | Matched Action |
---|---|---|
/api/v1/helloworld | HelloWorldController | Get |
/api/v2/helloworld | HelloWorld2Controller | Get |
/api/v3/helloworld | HelloWorld2Controller | GetV3 |
/api/v1/People | PeopleController | Get |
/api/v2/People | People2Controller | Get |
/api/v3/People | People2Controller | GetV3 |
varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddProblemDetails();builder.Services.AddApiVersioning();varapp=builder.Build();varpeople=app.NewVersionedApi();varv1=people.MapGroup("/people/v{version:apiVersion}").HasApiVersion(1.0);v1.MapGet("/",()=>new[]{newPerson()});app.Run();
- 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