Loading

asp.net core web api 版本控控制

通过微软的一个库Microsoft.AspNetCore.Mvc.Versioning实现asp.net core web api的版本控制。

以两种形式组织了Controller:

  • 文件夹分开
  • 命名不同但是路由是一样的

20191122103258-api-version-sln.png

需要注意的是,Microsoft.AspNetCore.Mvc.Versioning版本必须是>=3.1.0,不然相同路由会出现以下这样的错误:

20191122103258-api-version-error.png

URL Path Segment

在 URL 路径中添加版本,类似这样:

/api/v1/product
/api/v2/product

怎么实现呢?

Startup下的ConfigureServices方法加如下的配置:

 public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddApiVersioning(option =>
    {
        option.ReportApiVersions = true;
        option.AssumeDefaultVersionWhenUnspecified = true;
        option.DefaultApiVersion = new ApiVersion(1, 0);
    });
}

我们的Controller路由需要配置成如下,[ApiVersion("1.0")]控制访问当前的版本:

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/product")]
[ApiController]
public class ProductV1Controller : ControllerBase
{
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "Huwei Phone V1", "Xiaomi Phone V1", "Vivo Phone V1" };
    }
}

Startup的配置参数也要改一下:

 services.AddApiVersioning(option =>
{
    option.ReportApiVersions = true;
    option.ApiVersionReader = new QueryStringApiVersionReader("api-version");
    option.AssumeDefaultVersionWhenUnspecified = true;
    option.DefaultApiVersion = new ApiVersion(1, 0);
});

可以看到效果:

201911221106-url-result.gif

QueryString

通过url参数的方式也可以实现版本控制:

/api/production?api-version=1
/api/production?api-version=2

与上面不同的是controller只要用ApiVersion特性就够了,

[ApiVersion("1.0")]
[Route("api/[controller]")]
[ApiController]
public class ProductionController : ControllerBase
{
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "Huwei Phone V1", "Xiaomi Phone V1", "Vivo Phone V1" };
    }
}

201911221117-query-string-result.gif

版本信息可以放在url的参数中,可以放在url路径中,也可放在请求的header里,这样显的接口干净利索感知不到版本的存在。

和使用QueryString的实现方式大体一样,只是在配置中不一样,Contrller无需改动:

services.AddApiVersioning(option =>
{
    option.ReportApiVersions = true;
    //option.ApiVersionReader = new QueryStringApiVersionReader("api-version");
    option.ApiVersionReader = new HeaderApiVersionReader("api-version");
    option.AssumeDefaultVersionWhenUnspecified = true;
    option.DefaultApiVersion = new ApiVersion(1, 0);
});

20191122112942-header-result1.png

20191122113017-header-result2.png

三种实现方式对比

无论是什么配置都是支持Url Path Segement

根据option.ApiVersionReader参数的不同支持的会分别支持QueryStringHeader两种方式。

Microsoft.AspNetCore.Mvc.Versioning

各种特性的在不同场景的用法

ApiVersion

定义了当前Controller的版本,可以支持多个。

其中有个Deprecated参数:用于表示当前版本是否弃用的信息,当然接口还是可以正常调用的。

MapToApiVersion

如果一个Controller下有多个版本,有接口支持V1版本,有的接口支持V2版本,可以使用MapToApiVersion实现具体的哪个接口支持哪个版本调用,这个特性是打在具体的接口方法上的。

ApiVersionNeutral

如果你想一个Controller任意版本都可以调用,则可以加上该特性

参考

posted @ 2019-11-22 12:03  牧白  阅读(329)  评论(0编辑  收藏  举报