前言

大家周二好呀,.net core + Vue
这一系列基本就到这里差不多了,今天我又把整个系列的文章下边的全部评论看了一下(我是不是很负责哈哈),提到的问题基本都解决了,还有一些问题,已经在QQ群里讨论过了,今天再写一篇,然后给这个系列画一个暂时的句号吧,这些天也考虑写点儿啥,希望看到的小伙伴给点儿意见哟,其实我也是能力有限,不敢保证精通,不过只要想学,基本都能学到点儿东西的,至少至少能给大家在繁忙或者无聊的开发生涯中,多一点儿学习的动力吧,至少群里边的小伙伴是这样(马上破百了,快来加入我们吧),目前写的都是浅显的,打算下一步向架构师微服务方向简单拓展下,这两天简单看了一下,真是云里来雾里去,不是很通俗,还得自己啃,一起加油吧!!!

1、什么是版本控制

这个词语大家已经不会陌生,平时开发的时候,一定会用到过 Git 、SVN 或者 VSS (这三个我都用过,Git 应该是最好的),这个就是源代码的版本控制。

来句官方定义:版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理,是软件配置管理的核心思想之一。

那今天我们说的,就是 api接口的版本控制,这个大家一定也都接触到了,在我们使用的 swagger 中是这样的:



 

2、api版本控制的好处

简单来说,接口是APP的重要组成部分,数据是APP的核心,接口是连接APP和数据的纽带(这里的 APP 是广义上的接口调用者)。


一般情况下,我们项目中会有大量的接口,再加上版本的变化,接口的升级,一个接口,可能会有很多个稍有差异的接口,这个时候接口如果维护的不好,错一个就是一大片,那我们对
api 进行版本控制的好处有:

(1)有助于保护原有系统,不受影响,并及时修复问题
(2)可以实现用户的私人定制,(我之前接触过付费接口,可以这个意思)。
(3)快速迭代。

 

之前我在开发的时候,倒是没有考虑过这个问题,都是想当然的以为写代码只有一个版本,亦或者根本就没有版本概念,昨天晚上在看有一个小伙伴问到了 swagger
中,如何进行版本控制( 然后我想了想,在平时的开发中,我开发的项目中还没有遇到过版本控制,都是 web 项目+控制台项目,有问题就直接修改,有 bug
直接覆盖那种,从来没有考虑过版本,但是既然咱们这个系列是基于 api 接口的,版本应该是要有的,而且相信以后如果开发 api
项目的时候,也会遇到这个问题。我就研究了下 swagger 的源码,结合着网上的资料看了看,简单的配置了下,是这样的:



 

 

 

3、常见的版本控制有哪些?


通过上边的配置,我自认为很好的解决了这个问题,但是当我深入学习的时候,发现并不是,比如如何很好的调用不同版本的接口?,前端又如何对写好的接口地址进行快速修改?等等多个问题引起我的思考,通过搜索资料,我总结了以下,常见的版本控制有以下几个方案:

0、直接修改方法名,比如:/api/blog_v1,/api/blog_v2,/api/blog_v3... 虽然有时候也用,不过我直接 pass

1、通过路由控制,比如豆瓣:https://api.douban.com/v2/movie/in_theaters 
//本文重点说明,个人推荐,其他的大家可以参考博友文章

2、通过参数选择,比如:http://localhost:58427/api/Values?api-version=2.0

3、通过http请求的 Headers 来控制,接口地址不变,下边会说到 

4、利用 content type 来控制 

 

老张:本文只是一个说明版本,并没有把所有的方案都 code
出来,重点说了下路由控制,剩下的只是引导大家去思考这个问题,然后继续学习,毕竟会一两个方法就行了,平时开发中,使用的并不是很频繁,有好的想法欢迎下边留言,或者来群里和我们的小伙伴热情互动吧!

 

一、在 swagger 中通过路由实现版本控制

1、注册多个版本api

1、在 Blog.Core 项目下新建 SwaggerHelper 文件夹,然后添加 CustomApiVersion.cs 用来控制版本



 

2、在自定义API版本类中,添加枚举版本号
/// <summary> /// 自定义版本 /// </summary> public class CustomApiVersion { ///
<summary> /// Api接口版本 自定义 /// </summary> public enum ApiVersions { /// <summary>
/// v1 版本 /// </summary> v1 = 1, /// <summary> /// v2 版本 /// </summary> v2 = 2,
} }
 

3、在项目启动类 Startup.cs 中,配置服务,遍历版本展示

在 ConfigureServices 方法内,修改 services.AddSwaggerGen 中的 c.SwaggerDoc 文档如下:
//遍历出全部的版本,做文档信息展示 typeof(ApiVersions).GetEnumNames().ToList().ForEach(version
=> { c.SwaggerDoc(version, new Info { // {ApiName} 定义成全局变量,方便修改 Version =
version, Title= $"{ApiName} 接口文档", Description = $"{ApiName} HTTP API " +
version, TermsOfService= "None", Contact = new Contact { Name = "Blog.Core",
Email ="Blog.Core@xxx.com", Url = "https://www.jianshu.com/u/94102b59cc2a" }
}); });
 

 4、修改 SwagerUI 调用配置

在 Configure 方法内,修改 app.UseSwaggerUI 如下:
app.UseSwaggerUI(c => { //之前是写死的 //
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");//c.RoutePrefix =
"";//路径配置,设置为空,表示直接在根域名(localhost:8001)访问该文件 //根据版本名称倒序 遍历展示 typeof
(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version
=> { c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{ApiName} {version}
"); }); });
 

5、查看效果



现在已经实现了,在 swagger 中,进行多版本的展示,那要如何进行控制呢,请往下看。

 

2、对接口进行版本配置

1、刚刚我们已经创建好了多版本的接口文档,那现在就需要配置接口api了

在 BlogController.cs 中新建一个 V2_Blogtest() 方法:
/// <summary> /// 获取博客测试信息 v2版本 /// </summary> /// <returns></returns>
[HttpGet]//MVC自带特性 对 api 进行组管理 [ApiExplorerSettings(GroupName = "v2")] //路径 如果以
/ 开头,表示绝对路径,反之相对 controller 的想u地路径 [Route("/api/v2/blog/Blogtest")] public async
Task<object> V2_Blogtest() { return Ok(new { status = 220, data = "我是第二版的博客信息"
}); }
这里用到了 ApiExplorerSettings 特性,在mvc开发中,自带的一个组管理。

为什么要配置路径呢?是因为多版本的情况下,可能会出现重名函数,这里没有体现出来,因为使用的是 :V2_Blogtest
,下边的文章中会说到,如果一定要重名,需要怎么做。

 

2、这个时候查看效果,发现已经实现了我们文件开头的效果



 

 这个时候效果已经实现了,但是这么写显然不是很方便,首先,我们的组名 GroupName 是写死的 ”v2“,不利用拓展,然后呢,还需要再一次配置路由
Route,有小伙伴就发现了,既然这两个都是特性,有没有办法重写一个特性,把这两个合并呢,欸?!就是这样,请往下看。

 

3、自定义路由特性,实现路由+版本 双控制

1、在根目录的 SwaggerHelper 文件夹下,新建一个 CustomRouteAttribute.cs
/// <summary> /// 自定义路由 /api/{version}/[controler]/[action] /// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple
=true, Inherited = true)] public class CustomRouteAttribute : RouteAttribute,
IApiDescriptionGroupNameProvider {/// <summary> /// 分组名称,是来实现接口
IApiDescriptionGroupNameProvider/// </summary> public string GroupName { get;
set; } /// <summary> /// 自定义路由构造函数,继承基类路由 /// </summary> /// <param
name="actionName"></param> public CustomRouteAttribute(string actionName = "
[action]") : base("/api/{version}/[controller]/" + actionName) { } /// <summary>
/// 自定义版本+路由构造函数,继承基类路由 /// </summary> /// <param name="actionName"></param> ///
<param name="version"></param> public CustomRouteAttribute(ApiVersions version,
string actionName = "[action]") : base($"
/api/{version.ToString()}/[controller]/{actionName}") { GroupName =
version.ToString(); } }
 

2、对 api 接口进行设置
/// <summary> /// 获取博客测试信息 v2版本 /// </summary> /// <returns></returns>
[HttpGet]////MVC自带特性 对 api 进行组管理 //[ApiExplorerSettings(GroupName = "v2")] ///
/路径 如果以 / 开头,表示绝对路径,反之相对 controller 的想u地路径 //[Route("/api/v2/blog/Blogtest")] //
和上边的版本控制以及路由地址都是一样的 [CustomRoute(ApiVersions.v2, "Blogtest")] public async Task<
object> V2_Blogtest() { return Ok(new { status = 220, data = "我是第二版的博客信息" }); }
浏览效果都是一样的,这里就不展示了,从这里看出来,还是很方便的。

 说到这里,基于 swagger
的api接口版本控制已经说完了,采用的方法是路由控制,我个人感觉还是挺好的,当然文章的开头也说到了,还是有其他的方法,这里就简单的其中一个,个人不是很推荐,但是大家可以看看。

二、同名接口的版本控制

在上边咱们说到了,如果两个版本的方法名一定要一直咋办呢,重载大家肯定都知道,但是同一个 controller
接口方法肯定无论参数还是名称全部都一样,就连返回类型也一样,所以不能重载,那我们应该怎么办呢?,请往下看。

 

1、 在 controller 文件夹下,新建两个文件夹, v1、v2

2、然后添加相同的接口控制器 ApbController.cs,自定义即可



 

3、在两个控制器中,添加相同的代码



 

这样就能实现同名方法的版本控制了。

 

三、其他不适用于 swagger 的接口版本控制方法

这些方法我本打算写下来,发现不能通过 swagger 展示,会报错,只能通过 postman
测试,所以对我来说不是很完美,这里把博友的文章贴出来,大家可以自己看一下。

ASP.Net Core WebApi几种版本控制对比
<https://www.cnblogs.com/runningsmallguo/p/7484954.html>

ASP.NET Core API 版本控制
<https://www.cnblogs.com/tdfblog/p/asp-net-core-api-versioning.html>

Your API versioning is wrong, which is why I decided to do it 3 different
wrong ways <https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/>

 

 

四、Github

https://github.com/anjoy8/Blog.Core <https://github.com/anjoy8/Blog.Core>

https://gitee.com/laozhangIsPhi/Blog.Core
<https://gitee.com/laozhangIsPhi/Blog.Core>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信