1. 优点

  1. 有助于保护原有系统,不受影响,并及时修改问题
  2. 可以实现用户的私人定制(比如是付费接口)
  3. 快速迭代

2. API版本控制

  • 在URL中追加版本或者作为查询字符串参数
  • 通过自动以标头和通过接受标头

2.1 安装组件

ASP.NET API versioning为您提供了一种功能强大但易于使用的方法,用于将API版本控制语义添加到使用ASP.NET构建的新的和现有的REST服务中。API版本控制扩展定义了简单的元数据属性和约定,用于描述您的服务实现了哪些API版本。

    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="4.2.0" />

2.1.1 常用配置

[ApiVersion("1.1")] //设置版本号
[ApiVersionNeutral]//退出版本控制
[MapToApiVersion("1.1")] //设置独立版本
[ApiVersion("1.0", Deprecated = true)]//api版本已经被弃用
HttpContext.GetRequestedApiVersion().ToString(); //访问版本信息

2.2 QueryString来实现版本控制

2.2.1 ConfigureServices中配置

            //Versioning用来实现API的版本控制
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 1);//默认版本号
options.AssumeDefaultVersionWhenUnspecified = true;//此选项将用于不提供版本的请求,默认情况下假定API的版本为1.0
options.ReportApiVersions = true;//当设置为true时候,api将返回响应标头中支持的版本信息
//下面这句默认不写也可以
//options.ApiVersionReader = new QueryStringApiVersionReader(parameterNames: "api-version");//该名称用于查询时候使用
});

2.2.2 控制器设置版本

namespace NetCore_SwaggerVersion.Controllers.v1
{
/// <summary>
/// 版本1.1
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("1.1")]//可以设置多个
[ApiVersion("1.2")]
public class TestController : ControllerBase namespace NetCore_SwaggerVersion.Controllers.v2
{
/// <summary>
/// 版本2.0
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("2.6")]
public class TestController : ControllerBase

不同命名空间下可以存在相同的控制器

2.2.3 特定方法设置版本

[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()

2.2.4 设置不受版本控制

    [ApiVersionNeutral]//退出版本控制
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase

2.3.5 访问地址

http://localhost:5000/api/WeatherForecast/Get //不写版本号的话走的是默认的版本号
http://localhost:5000/api/Test?api-version=1.1
http://localhost:5000/api/Test?api-version=1.2
http://localhost:5000/api/Test?api-version=2.6

2.3 URL Path Segment来实现版本控制

2.3.1 ConfigureServices中配置

            //Versioning用来实现API的版本控制
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 1);//默认版本号
options.AssumeDefaultVersionWhenUnspecified = true;//此选项将用于不提供版本的请求,默认情况下假定API的版本为1.0
options.ReportApiVersions = true;//当设置为true时候,api将返回响应标头中支持的版本信息
});

2.3.2 控制器设置版本

namespace NetCore_SwaggerVersion.Controllers.v1
{
/// <summary>
/// 版本1.1
/// </summary>
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ApiVersion("1.0")]
[ApiVersion("1.1")]//定义控制器提供哪个版本的API
public class TestController : ControllerBase namespace NetCore_SwaggerVersion.Controllers.v2
{
/// <summary>
/// 版本2.0
/// </summary>
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ApiVersion("2.6")]
public class TestController : ControllerBase

不同命名空间下可以存在相同的控制器

2.3.3 特定方法设置版本

[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()

2.3.4 设置不受版本控制

    [ApiVersionNeutral]//退出版本控制
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase

2.3.5 访问地址

http://localhost:5000/api/v1.0/Test
http://localhost:5000/api/v1.1/Test
http://localhost:5000/api/v2.6/Test
http://localhost:5000/api/WeatherForecast/Get 不受版本控制

2.4 HTTP Headers来实现版本控制

2.4.1 ConfigureServices中配置

            //Versioning用来实现API的版本控制
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 1);//默认版本号
options.AssumeDefaultVersionWhenUnspecified = true;//此选项将用于不提供版本的请求,默认情况下假定API的版本为1.0
options.ReportApiVersions = true;//当设置为true时候,api将返回响应标头中支持的版本信息
//header传递版本信息
options.ApiVersionReader = new HeaderApiVersionReader("version");
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);//如果没有传输版本号,那么会使用最大版本号 LowestImplementedApiVersionSelector是最小版本号
options.UseApiBehavior = false;//是否使用API行为
});

2.4.2 控制器设置版本

namespace NetCore_SwaggerVersion.Controllers.v1
{
/// <summary>
/// 版本1.1
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("1.1")]//定义控制器提供哪个版本的API
public class TestController : ControllerBase namespace NetCore_SwaggerVersion.Controllers.v2
{
/// <summary>
/// 版本2.0
/// </summary>
[Route("api/[controller]")]
[ApiController]
[ApiVersion("2.6")]
public class TestController : ControllerBase

不同命名空间下可以存在相同的控制器

2.4.3 特定方法设置版本

[MapToApiVersion("1.1")]
[HttpGet]
public IEnumerable<string> Get()

2.4.4 设置不受版本控制

    [ApiVersionNeutral]//退出版本控制
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase

2.4.5 访问地址

http://localhost:5000/api/Test  //需要在headers里面增加 version: 1.1
http://localhost:5000/api/WeatherForecast/Get 不受版本控制

2.5 同时支持多种模式

services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
o.ApiVersionReader = ApiVersionReader.Combine(new HeaderApiVersionReader("api-version"), new QueryStringApiVersionReader("api-version"));
//或者
//同时支持查询字符串和标头
o.ApiVersionReader = new QueryStringOrHeaderApiVersionReader(parameterName: "version"){HeaderNames = { "api-version", "x-ms-version" }}
});

2.6 不借助包,封装文件

public class NameSpaceVersionRoutingConvention:IApplicationModelConvention
{
private readonly string apiPrefix;
private const string urlTemplate = "{0}/{1}/{2}";
public NameSpaceVersionRoutingConvention(string apiPrefix = "api")
{
this.apiPrefix = apiPrefix;
} public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{ var hasRouteAttribute = controller.Selectors
.Any(x => x.AttributeRouteModel != null);
if (!hasRouteAttribute)
{
continue;
}
var nameSpaces = controller.ControllerType.Namespace.Split('.');
//获取namespace中版本号部分
var version = nameSpaces.FirstOrDefault(x => Regex.IsMatch(x, @"^v(\d+)$"));
if (string.IsNullOrEmpty(version))
{
continue;
}
string template = string.Format(urlTemplate, apiPrefix, version,
controller.ControllerName);
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
{
Template = template
};
}
}
}

调试代码发现这种方式只在程序第一次运行的时候会执行,之后不会再执行多次,因此效率很高。

借鉴于:https://www.cnblogs.com/runningsmallguo/p/7484954.html

参考文档

https://github.com/microsoft/aspnet-api-versioning

微信公众号

.NET之API版本控制的更多相关文章

  1. ****Web API 版本控制的几种方式

    个人建议:用content type,即放在Header里面!比如加一个Version:1.4.3 这篇文章写得很好,介绍了三种实现web api版本化的三种方式.我从评论里又收集到两种方式,所以一共 ...

  2. ASP.NET Core API 版本控制

    几天前,我和我的朋友们使用 ASP.NET Core 开发了一个API ,使用的是GET方式,将一些数据返回到客户端 APP.我们在前端进行了分页,意味着我们将所有数据发送给客户端,然后进行一些dat ...

  3. asp.net web api 版本控制

    版本控制   版本控制的方法有很多,这里提供一种将Odata与普通web api版本控制机制统一的方法,但也可以单独控制,整合控制与单独控制主要的不同是:整合控制通过VersionController ...

  4. .Net Core中的Api版本控制

    原文链接:API Versioning in .Net Core 作者:Neel Bhatt 简介 Api的版本控制是Api开发中经常遇到的问题, 在大部分中大型项目都需要使用到Api的版本控制 在本 ...

  5. 【转】.Net Core中的Api版本控制

    原文链接:API Versioning in .Net Core 作者:Neel Bhatt 简介 Api的版本控制是Api开发中经常遇到的问题, 在大部分中大型项目都需要使用到Api的版本控制 在本 ...

  6. 微服务设计 - api版本控制

    要描述了几种API版本控制的方法.用户可以查询原始的API,或者添加定制的头文件来接收特定的版本.如果应用程序收到一个重大修订,将URI修改为V2.在进行迭代改进时,将创建与更改日期相一致的端点,并允 ...

  7. 【转】ASP.NET Core API 版本控制

    几天前,我和我的朋友们使用 ASP.NET Core 开发了一个API ,使用的是GET方式,将一些数据返回到客户端 APP.我们在前端进行了分页,意味着我们将所有数据发送给客户端,然后进行一些dat ...

  8. API 版本控制的几种方式

    个人建议:用content type,即放在Header里面!比如加一个Version:1.4.3 这篇文章写得很好,介绍了三种实现web api版本化的三种方式.我从评论里又收集到两种方式,所以一共 ...

  9. 【ASP.NET Core】ASP.NET Core API 版本控制

    几天前,我和我的朋友们使用 ASP.NET Core 开发了一个API ,使用的是GET方式,将一些数据返回到客户端 APP.我们在前端进行了分页,意味着我们将所有数据发送给客户端,然后进行一些dat ...

  10. .net core 实现 api网关 进行 api版本控制

    场景: 由一次大的项目改动引起的app端api不兼容问题,这时候就需要对api做版本控制了,权衡之后因为用户不多,选择了强更,没人想在已经写了8000行代码的单个svc文件中维护好几个版本的接口或者继 ...

随机推荐

  1. 【LeetCode】2020-04 每日一题

    8. 字符串转换整数 (atoi)(中等) [分类]:模拟.正则表达式 [题解]: 解法1:直接模拟,但是在判断INT_MAX和INT_MIN上需要注意,因为直接判断会超出范围,所以可以将式子转换一下 ...

  2. Flutter Widget中的State

    一.Flutter 的声明式视图开发 在原生系统(Android.iOS)或原生JavaScript 开发的话,应该知道视图开发是命令式的,需要精确地告诉操作系统或浏览器用何种方式去做事情. 比如,如 ...

  3. 翻译:《实用的Python编程》09_01_Packages

    目录| 上一节 (8.3 调试) | 下一节 (9.2 第三方包) 9.1 包 如果编写一个较大的程序,我们并不真的想在顶层将其组织为一个个独立文件的大型集合.本节对包(package)进行介绍. 模 ...

  4. Java【线程池、Lambda表达式】

    见pdf 等待唤醒机制 wait和notify 第二章 线程池 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低 系统的效率,因为频繁创建线程和销毁 ...

  5. C++运算符重载的一些困惑

    一.背景 在复习<C++基础与提高>时,自己实现运算符重载(i++)时,几次都报错.其实还是自己对运算符重载这一部分内容理解得不够透彻,于是再次看了下书上的内容,理解算是加深了一些,于是提 ...

  6. Day15_87_通过反射机制获取某个特定的方法

    通过反射机制获取某个特定的方法 反射是通过 方法名+形参列表来区分各个方法的(形参列表要用class类型.加.class) 示例代码 import java.lang.reflect.Method; ...

  7. 使用docker快速安装软件

    安装mysql mkdir /opt/mysql /opt/mysql/etc /opt/mysql/data docker run -itd --name mariadb -e MYSQL_ROOT ...

  8. Qt获取一张图片的平均色(主色调)

    这两天在一个小工具中想做一个图标的发光效果,用固定颜色做出来效果很丑,于是想到此方法,得到图标的主色调后,将颜色调亮,并设置为阴影颜色,从而达到类似发光的效果. 本文章主要在于得到一张图片的平均色,并 ...

  9. 869. Reordered Power of 2

    Starting with a positive integer N, we reorder the digits in any order (including the original order ...

  10. win 远程桌面 ubuntu

    开始 起因 因为工作需求经常要远程 局域网内的 Ubuntu设备 之前用的一直是 Teamviver 但是最近不知怎么了,Teamviver发病 打不开了,也懒得折腾了! 简单的记录一下 能用的几种连 ...