使用.NET 6开发TodoList应用(21)——实现API版本控制

  • A+
所属分类:.NET技术
摘要

API接口版本管理,对于一些规模稍大的企业应用来说,是经常需要关注的一大需求。尽管我们的示例程序TodoList很简单,但是我们也可以通过这个应用程序,来实践一下如何管理API接口版本。


系列导航及源代码

需求

API接口版本管理,对于一些规模稍大的企业应用来说,是经常需要关注的一大需求。尽管我们的示例程序TodoList很简单,但是我们也可以通过这个应用程序,来实践一下如何管理API接口版本。

目标

实现API接口版本管理。

原理与思路

要实现API版本管理,我们需要这个库:Microsoft.AspNetCore.Mvc.Versioning。它提供了.NET Web项目接口的版本管理功能。

实现

添加Nuget Package并配置服务

Api项目中添加Microsoft.AspNetCore.Mvc.Versioning包。并添加一个扩展方法:

  • ApiServiceExtensions.cs
using Microsoft.AspNetCore.Mvc;  namespace TodoList.Api.Extensions;  public static class ApiServiceExtensions {     public static void ConfigureApiVersioning(this IServiceCollection services)     {         services.AddApiVersioning(options =>         {             // 向响应头中添加API版本信息             options.ReportApiVersions = true;             // 如果客户端不显式指定API版本,则使用默认版本             options.AssumeDefaultVersionWhenUnspecified = true;             // 配置默认版本为1.0             options.DefaultApiVersion = new ApiVersion(1, 0);         });     } } 

Program中调用:

  • Program.cs
// 省略其他... builder.ConfigureLog(); builder.Services.ConfigureApiVersioning(); 

实现API版本控制

方法1: 添加ApiVersion属性

我们复制一份TodoItemController到新文件TodoItemV2Controller并修改类名和构造函数,其他保持原样。为了给Controller标记对应的API版本号,我们分别向两个Controller上添加属性:

[ApiVersion("2.0")] [Route("/todo-item")] [ApiController] public class TodoItemV2Controller : ControllerBase {     private readonly IMediator _mediator;     // 省略其他... } 

以及

[ApiVersion("1.0")] [Route("/todo-item")] [ApiController] public class TodoItemController : ControllerBase {     private readonly IMediator _mediator;     // 省略其他.. } 
验证1: 请求中不添加任何API版本相关字段

启动Api项目,执行查询TodoItem的请求:

  • 请求
    使用.NET 6开发TodoList应用(21)——实现API版本控制

-** 响应**
日志输出:
使用.NET 6开发TodoList应用(21)——实现API版本控制
结果返回:
使用.NET 6开发TodoList应用(21)——实现API版本控制
以及响应头信息中包含的api-supported-versions
使用.NET 6开发TodoList应用(21)——实现API版本控制

验证2: 请求中添加查询字符串api-version

启动Api项目,执行查询TodoItem的请求:

  • 请求
    使用.NET 6开发TodoList应用(21)——实现API版本控制

  • 响应
    日志输出:
    使用.NET 6开发TodoList应用(21)——实现API版本控制
    结果返回(可以自己尝试修改内部逻辑,这里我懒了没改实现,不过从日志已经能看出请求确实进入了V2版本的Controller):
    使用.NET 6开发TodoList应用(21)——实现API版本控制
    以及响应头信息中包含的api-supported-versions
    使用.NET 6开发TodoList应用(21)——实现API版本控制

方法2: 通过请求头携带API版本信息

为了实现这一点,需要在ConfigureApiVersioning中增加配置:

  • ApiServiceExtensions.cs
// 省略其他... // 指定请求头中携带用于指定API版本信息的字段 options.ApiVersionReader = new HeaderApiVersionReader("api-version"); 
验证3: 通过请求头携带API版本信息

启动Api项目,执行查询TodoItem的请求:

  • 请求
    使用.NET 6开发TodoList应用(21)——实现API版本控制

  • 响应
    日志输出:
    使用.NET 6开发TodoList应用(21)——实现API版本控制
    返回结果就不继续贴了,以及响应头信息中包含的api-supported-versions
    使用.NET 6开发TodoList应用(21)——实现API版本控制

方法3: 通过URL路径访问对应的版本

除了这种之外的以上几种方法,都不需要修改接口的URI,而这种方式需要修改URI路径。我们在两个Controller上修改URI如下:

[ApiVersion("2.0")] [Route("/{v:apiVersion}/todo-item")] [ApiController] // 省略其他... 
验证4: 通过URI路径选择API版本

启动Api项目,执行查询TodoItem的请求:

  • 请求
    使用.NET 6开发TodoList应用(21)——实现API版本控制

  • 响应
    日志输出:
    使用.NET 6开发TodoList应用(21)——实现API版本控制
    返回结果就不继续贴了,以及响应头信息中包含的api-supported-versions
    使用.NET 6开发TodoList应用(21)——实现API版本控制

一点扩展

有的时候我们需要标记一个版本的请求为deprecated,但是还不想完全删除这个Controller,可以用下面的方式进行标记,这样返回头中会指出这个版本的API已经处于deprecated状态了。

[ApiVersion("2.0", Deprecated = true)] [Route("/{v:apiVersion}/todo-item")] [ApiController] // 省略其他... 

或者在ConfigureApiVersioning中使用Convention进行标记:

// 省略其他... // 使用Convention标记deprecated options.Conventions.Controller<TodoItemV2Controller>().HasDeprecatedApiVersion(new ApiVersion(2, 0)); 

我们再请求2.0版本的API时,仍然可以获取数据,但是得到的返回头中信息如下:
使用.NET 6开发TodoList应用(21)——实现API版本控制
对比使用Convention方式标记的返回头:
使用.NET 6开发TodoList应用(21)——实现API版本控制

总结

在本文中我们使用多种方式实现了管理API版本的需求,可以根据具体的需要选择一种进行实现。下一篇我们介绍关于响应的缓存实现。