ASP.NET Core API 版本控制实践

随着Web API的不断迭代,为了确保旧版本的客户端能够正常工作,需要在API中添加版本控制功能。在ASP.NET Core中实现版本控制,首先需要在Startup类中配置服务,然后选择一种版本控制策略,比如通过查询字符串、URL或HTTP头部来实现。

在本文中,将探讨如何通过不同的方式在ASP.NET Core中实现API版本控制,并讨论每种方法的优缺点。

配置服务

ASP.NET Core的Startup类中配置服务时,可以设置以下属性:

  • ReportApiVersions:在响应中添加api-supported-versions头部,列出支持的API版本。
  • AssumeDefaultVersionWhenUnspecified:如果客户端没有指定版本,则使用默认版本;否则返回UnsupportedApiVersion错误。
  • DefaultApiVersion:使用ApiVersion指定默认版本号。
  • ApiVersionReader:指定版本号的读取位置,默认为查询字符串。如果要使用HTTP头部,则需要进行配置。
  • Conventions:可以在这里指定各个控制器的版本号,而不是使用[ApiVersion]属性。

此外,可以使用HttpContext的GetRequestedApiVersion方法获取当前请求的版本,该方法返回ApiVersion类型。

默认的版本号指定方法是通过查询字符串中的api-version参数。例如:

/movies?api-version=2.0

以下是一个通过查询字符串访问不同版本的示例:

[ApiVersion("1.0")] [Route("movies")] public class MoviesControllerV1 : Controller { [HttpGet] public IActionResult Get() => Content("Version 1"); } [ApiVersion("2.0")] [Route("movies")] public class MoviesControllerV2 : Controller { [HttpGet] public IActionResult Get() => Content("Version 2"); }

在这个例子中,MoviesControllerV1和MoviesControllerV2分别对应API的1.0和2.0版本。

可以通过路由和apiVersion约束在URL中指定版本号。需要注意的是,如果使用URL指定版本号,查询字符串中的版本号将不再起作用:

[ApiVersion("2.0")] [Route("actors/v{ver:apiVersion}")] public class ActorsControllerV2 : Controller { [HttpGet] public IActionResult Get() => Content("Version 2"); }

在这个例子中,ActorsControllerV2的URL中包含了版本号2.0。

要使用HTTP头部传递版本号,首先需要配置版本读取器,告诉中间件如何读取版本。配置完成后,查询字符串中的版本号将不再起作用:

options.ApiVersionReader = new HeaderApiVersionReader("api-version");

在这个例子中,使用了"api-version"作为HTTP头部的键,以保持与查询字符串和URL方法的一致性。

如果不使用[ApiVersion]属性,可以通过Conventions属性配置控制器的版本号:

options.Conventions.Controller() .HasApiVersion(new ApiVersion(1, 0)); options.Conventions.Controller() .HasApiVersion(new ApiVersion(2, 0));

在这个例子中,WritersControllerV1和WritersControllerV2分别对应API的1.0和2.0版本,而不需要额外的属性。

还可以使用[MapToApiVersion]属性在控制器内部对操作方法进行版本控制:

[ApiVersion("1.0")] [ApiVersion("2.0")] [Route("directors")] public class DirectorsController : Controller { [HttpGet] public IActionResult Get() => Content("Version 1"); [HttpGet, MapToApiVersion("2.0")] public IActionResult GetV2() => Content("Version 2"); }

在这个例子中,DirectorsController的Get方法对应API的1.0版本,而GetV2方法对应API的2.0版本。

可以通过设置[ApiVersion]属性的Deprecated属性来指定API的某个版本是否已弃用:

[ApiVersion("1.0", Deprecated = true)] [Route("genres")] public class GenresControllerV1 : Controller { [HttpGet] public IActionResult Get() => Content("Version 1"); } [ApiVersion("2.0")] [Route("genres")] public class GenresControllerV2 : Controller { [HttpGet] public IActionResult Get() => Content("Version 2"); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485