前言

大家周二好呀,.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 = ,
/// <summary>
/// v2 版本
/// </summary>
v2 = ,
}
}

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 = , 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 = , data = "我是第二版的博客信息" }); }

浏览效果都是一样的,这里就不展示了,从这里看出来,还是很方便的。

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

二、同名接口的版本控制

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

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

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

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

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

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

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

ASP.Net Core WebApi几种版本控制对比

ASP.NET Core API 版本控制

Your API versioning is wrong, which is why I decided to do it 3 different wrong ways

四、Github

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

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

从壹开始前后端分离 [.netCore 填坑 ] 三十四║Swagger:API多版本控制,带来的思考的更多相关文章

  1. k.tt 研究下生成的逻辑代码:从壹开始前后端分离 [.netCore 填坑 ] 三十二║ 四种方法快速实现项目的半自动化搭建

    更新 1.更新小伙伴 @大龄Giser 提出好点子:试试VS的插件扩展:VSIX.ItemProject等,将T4模板给制作插件,这里先记下,有懂的小伙伴可以自己先试试,我会在以后更新. 2.感谢小伙 ...

  2. 从壹开始前后端分离 [.netCore 填坑 ] 三十三║ ⅖ 种方法实现完美跨域

    缘起 哈喽大家周四好,趁着大家在团建的时候花一个下午学点儿东西,也是督促大家学习哟,希望大家看到老张的文章,可以有一丢丢的学习动力.不过话说过来,该吃的团建还是要去的,不能学我呀 [ /(ㄒoㄒ)/~ ...

  3. 从壹开始前后端分离 [.netCore 不定期更新 ] 三十五║ 完美实现全局异常日志记录

    缘起 哈喽我是不定期更新的日常,昨天群里小伙伴问到了记录日志,当然,以前我也挖过这个坑,后来一直没有来得及填上,也想着 swagger 一直又有错误信息展示的功能,就迟迟没有添加这个功能,不过昨天夜里 ...

  4. 采用异步来实现重新连接服务器或者重新启动服务 C#中类的属性的获取 SignalR2简易数据看板演示 C#动态调用泛型类、泛型方法 asp .net core Get raw request. 从壹开始前后端分离[.NetCore 不定期更新] 38 ║自动初始化数据库

    采用异步来实现重新连接服务器或者重新启动服务 开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端! #region 检测断线并重连OPC服务 ...

  5. 从壹开始前后端分离[.NetCore] 37 ║JWT完美实现权限与接口的动态分配

    缘起 本文已经有了对应的管理后台,地址:https://github.com/anjoy8/Blog.Admin 哈喽大家好呀!又过去一周啦,这些天小伙伴们有没有学习呀,已经有一周没有更新文章了,不过 ...

  6. 从壹开始前后端分离[.netCore 不定期 ] 36 ║解决JWT自定义中间件授权过期问题

    缘起 哈喽,老张的不定期更新的日常又开始了,在咱们的前后端分离的.net core 框架中,虽然已经实现了权限验证<框架之五 || Swagger的使用 3.3 JWT权限验证[修改]>, ...

  7. 从壹开始前后端分离[.NetCore ] 38 ║自动初始化数据库(不定期更新)

    缘起 哈喽大家好呀,我们又见面啦,这里先祝大家圣诞节快乐哟,昨天的红包不知道有没有小伙伴抢到呢.今天的这篇内容灰常简单,只是对我们的系统的数据库进行CodeFirst,然后就是数据处理,因为这几个月来 ...

  8. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十二 || 三种跨域方式比较,DTOs(数据传输对象)初探

    更新反馈 1.博友@落幕残情童鞋说到了,Nginx反向代理实现跨域,因为我目前还没有使用到,给忽略了,这次记录下,为下次补充.此坑已填 2.提示:跨域的姊妹篇——<三十三║ ⅖ 种方法实现完美跨 ...

  9. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单

    前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...

随机推荐

  1. 【BZOJ2339】【HNOI2011】卡农

    题解: 首先用二进制表示每个音阶是否使用,那么共有$2^{n}-1$(空集不可行)种片段,用$a_{i}$来表示每个片段,问题就是求满足$a_{1}\left (xor\right)a_{2}\lef ...

  2. 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子

    Description Sulotion 首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的 如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否 大概就用这种思路,f[x][y] ...

  3. BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理

    BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理 Description 给定方程     X1+X2+. +Xn=M 我们对第l..N1个变量进行一些限制: Xl < = A ...

  4. BZOJ_4128_Matrix_矩阵乘法+哈希+BSGS

    BZOJ_4128_Matrix_矩阵乘法+哈希+BSGS Description 给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p) Input 第一行两个整数n和p,表示矩阵的 ...

  5. js默认参数实现方法

    function simue (){ var a = arguments[0] ? arguments[0] : 1; var b = arguments[1] ? arguments[1] : 2; ...

  6. 第十四章——循环神经网络(Recurrent Neural Networks)(第一部分)

    由于本章过长,分为两个部分,这是第一部分. 这几年提到RNN,一般指Recurrent Neural Networks,至于翻译成循环神经网络还是递归神经网络都可以.wiki上面把Recurrent ...

  7. Eureka的功能特性及相关配置

    1.服务提供者1.1服务注册服务提供者启动时,会通过rest请求的方式将自己注册到Eureka Server上,同时带上了自身服务的一些元数据信息.Eureka Server接收到请求后,将元数据信息 ...

  8. OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Redis使用

    OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ...

  9. 关于Redis的常见面试题解析

    1. 使用redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...

  10. 从壹开始前后端分离[.NetCore ] 38 ║自动初始化数据库(不定期更新)

    缘起 哈喽大家好呀,我们又见面啦,这里先祝大家圣诞节快乐哟,昨天的红包不知道有没有小伙伴抢到呢.今天的这篇内容灰常简单,只是对我们的系统的数据库进行CodeFirst,然后就是数据处理,因为这几个月来 ...