Web API 的版本化能够尽量保障在雷同url状况下保留一个 api 的多个版本,通常一个 webapi 会有多个client,这些client包含:app,web,html5,crawl 等等同构或者异构的平台,当 api 降级之后,往往降级前的 api 也得保留,当保护两个api的时候就是一个不小的挑战,毕竟还是存在一些 client 用户须要拜访老的api,这时候就须要将 webapi 版本化。
装置 Versioning 包
要想应用 webapi 的版本化性能,须要用 nuget 援用 Microsoft.AspNetCore.Mvc.Versioning
包,还能够通过 Visual Studio 2019 的 NuGet package manager
可视化界面装置 或者 通过 NuGet package manager
命令行工具输出以下命令:
dotnet add package Microsoft.AspNetCore.Mvc.Versioning
启动 API 版本化
当包胜利增加到我的项目之后,接下来就能够在 Startup.ConfigureServices
中将 ApiVersioning 注入到容器中,如下代码所示:
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddApiVersioning(); } }
在调用 AddApiVersioning()
的时候记得 using Microsoft.AspNetCore.Mvc.Versioning
,除了这个默认办法,还能够做一些全局配置,如下代码所示:
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddApiVersioning(v => { v.ReportApiVersions = true; v.AssumeDefaultVersionWhenUnspecified = true; v.DefaultApiVersion = new ApiVersion(1, 0); }); } }
应用 QueryString 指定版本号
先来看一下代码,思考如下的 api。
[ApiController] [ApiVersion("2.0")] [Route("api/[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
从代码中能够看到,我在 WeatherForecastController 上标记了该 Controller 是 v2.0 版本,接下来如何拜访呢? 能够通过如下链接: http://localhost:61582/api/weatherforecast?api-version=2.0
看到这里,有些敌人就有疑难了,v2.0
的 Get 是有了,那 v1.0
的 Get 怎么拜访呢? 理论开发中的做法是这样的,会用两个命名空间来示意相应的版本号,能够看如下代码:
namespace WebApplication6.Controllers.v1{ [ApiController] [ApiVersion("1.0")] [Route("api/[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }}namespace WebApplication6.Controllers.v2{ [ApiController] [ApiVersion("2.0")] [Route("api/[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }}
从下面代码能够看到 WebApplication6.Controllers.v1
示意版本 v1.0 , WebApplication6.Controllers.v2
示意版本 v2.0,接下来顺次浏览这两个url。
应用 routes 指定版本号
很显然应用 QueryString 的形式不是很优雅也不合乎 Restful 标准,接下来看一下如何通过 Route 革新,思考上面的类,请留神我是如何在 route 中进行版本化的。
[ApiController] [ApiVersion("1.0")] [Route("api/v{version:apiVersion}/[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
在这里,我将 [Route("api/[controller]")]
替换成了 [Route("api/v{version:apiVersion}/[controller]")]
,接下来将我的项目跑起来,如下图所示:
疏忽 API 版本
在 API 版本化时,有些 API 可能只有一个版本的需要,这时候能够应用 ApiVersionNeutral
个性来漠视版本化,如下代码所示:
[ApiVersionNeutral] [Route("api/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
译文链接:https://www.infoworld.com/art...
更多高质量干货:参见我的 GitHub: csharptranslate