OData – API Versioning

前言

OData versioning 和普通 Web API versioning 最大区别就是 EDM 是否换了. 

Web API 可能只是操作的细节换掉了, 我们就可以开一个新的 version. 但是 EDM 换就很大动作了. 就好比, 一个操作换了和一个数据结构换了的区别.

主要参考

API versioning extension with ASP.NET Core OData 8

没有换 EDM 的情况

就那我的例子来说, Web API 和 OData share 一个 Controller. 我的 Web API 要做 versioning, 但 OData 我的 EDM 没有不同的话. 大概长这样

    [ApiController]
    [ApiVersion("1.0")]
    [ApiVersion("2.0")]
    [Route("api/v{version:apiVersion}")]
    public class MyController : ControllerBase
    {
        [ODataAttributeRouting]
        [HttpGet("products"), MapToApiVersion("1.0")] // api/v1.0/products
        [EnableQuery]
        public IEnumerable<Product> GetXyz_v1()
        {
            return _products;
        }

        [ODataAttributeRouting]
        [HttpGet("products"), MapToApiVersion("2.0")] // api/v2.0/products
        [EnableQuery]
        public IEnumerable<Product> GetXyz_v2()
        {
            return _products;
        }

        [ODataAttributeRouting]
        [HttpGet("products/{id}")]
        [HttpGet("products({id})")]
        [EnableQuery]
        public Product GetAbc(int id)
        {
            return _products.Single(p => p.Id == id);
        }

        [HttpPost("products"), MapToApiVersion("1.0")]
        public ActionResult<Product> CreateProduct_v1([FromBody] CreateProductDTO dto)
        {
            return Ok();
        }

        [HttpPost("products"), MapToApiVersion("2.0")]
        public ActionResult<Product> CreateProduct_v2([FromBody] CreateProductDTO dto)
        {
            return Ok();
        }

        private readonly Product[] _products = new[]
        {
             new Product { Id = 1, Name = "n1" },
             new Product { Id = 2, Name = "n2" }
        };
    }

program.cs

builder.Services.AddControllers().AddOData(options =>
{
    options.TimeZone = TimeZoneInfo.Utc;
    options.Select().Expand().Filter().OrderBy().SetMaxTop(null).Count();
    var builder = new ODataConventionModelBuilder();
    builder.EnableLowerCamelCase();
    builder.EntitySet<Product>("Products");
    options.AddRouteComponents("api/v{version:apiVersion}", builder.GetEdmModel());
});
builder.Services.AddApiVersioning(options => {
    options.ReportApiVersions = true;
});

api/v{version:apiVersion} 这个必须和 route("api/v{version:apiVersion}") 一模一样就可以了. 

如果要做不同的 EDM, 就是参考上面的文章, 扩展 OData, 或者一个 Controller 一个 version, 不要用 api/v{version:apiVersion}

类似这样

options.AddRouteComponents("api/v1", builder.GetEdmModel());
options.AddRouteComponents("api/v2", builder2.GetEdmModel());

然后 route("api/v1")

我没有测试行不行,以后有需求再来补上扩展 OData 的呗

MyODataRoutingApplicationModelProvider
原文地址:https://www.cnblogs.com/keatkeat/p/15459972.html