從壹開始先後端分離 [.netCore 填坑 ] 三十四║Swagger:API多版本控制,帶來的思考

前言

你們週二好呀,.net core + Vue 這一系列基本就到這裏差很少了,今天我又把整個系列的文章下邊的所有評論看了一下(我是否是很負責哈哈),提到的問題基本都解決了,還有一些問題,已經在QQ羣裏討論過了,今天再寫一篇,而後給這個系列畫一個暫時的句號吧,這些天也考慮寫點兒啥,但願看到的小夥伴給點兒意見喲,其實我也是能力有限,不敢保證精通,不過只要想學,基本都能學到點兒東西的,至少至少能給你們在繁忙或者無聊的開發生涯中,多一點兒學習的動力吧,至少羣裏邊的小夥伴是這樣(立刻破百了,快來加入咱們吧),目前寫的都是淺顯的,打算下一步向架構師微服務方向簡單拓展下,這兩天簡單看了一下,真是雲裏來霧裏去,不是很通俗,還得本身啃,一塊兒加油吧!!!html

一、什麼是版本控制

這個詞語你們已經不會陌生,平時開發的時候,必定會用到過 Git 、SVN 或者 VSS (這三個我都用過,Git 應該是最好的),這個就是源代碼的版本控制。前端

來句官方定義:版本控制是指對軟件開發過程當中各類程序代碼、配置文件及說明文檔等文件變動的管理,是軟件配置管理的核心思想之一。git

那今天咱們說的,就是 api接口的版本控制,這個你們必定也都接觸到了,在咱們使用的 swagger 中是這樣的:github

 

二、api版本控制的好處

簡單來講,接口是APP的重要組成部分,數據是APP的核心,接口是鏈接APP和數據的紐帶(這裏的 APP 是廣義上的接口調用者)。web

通常狀況下,咱們項目中會有大量的接口,再加上版本的變化,接口的升級,一個接口,可能會有不少個稍有差別的接口,這個時候接口若是維護的很差,錯一個就是一大片,那咱們對 api 進行版本控制的好處有:json

(1)有助於保護原有系統,不受影響,並及時修復問題
(2)能夠實現用戶的私人定製,(我以前接觸過付費接口,能夠這個意思)。
(3)快速迭代。api

 

以前我在開發的時候,卻是沒有考慮過這個問題,都是想固然的覺得寫代碼只有一個版本,亦或者根本就沒有版本概念,昨天晚上在看有一個小夥伴問到了 swagger 中,如何進行版本控制( 而後我想了想,在平時的開發中,我開發的項目中尚未遇到過版本控制,都是 web 項目+控制檯項目,有問題就直接修改,有 bug 直接覆蓋那種,歷來沒有考慮過版本,可是既然我們這個系列是基於 api 接口的,版本應該是要有的,並且相信之後若是開發 api 項目的時候,也會遇到這個問題。我就研究了下 swagger 的源碼,結合着網上的資料看了看,簡單的配置了下,是這樣的:架構

 

 

 

三、常見的版本控制有哪些?

經過上邊的配置,我自認爲很好的解決了這個問題,可是當我深刻學習的時候,發現並非,好比如何很好的調用不一樣版本的接口?,前端又如何對寫好的接口地址進行快速修改?等等多個問題引發個人思考,經過搜索資料,我總結了如下,常見的版本控制有如下幾個方案:mvc

0、直接修改方法名,好比:/api/blog_v1,/api/blog_v2,/api/blog_v3... 雖然有時候也用,不過我直接 passapp

一、經過路由控制,好比豆瓣:https://api.douban.com/v2/movie/in_theaters  //本文重點說明,我的推薦,其餘的你們能夠參考博友文章

二、經過參數選擇,好比:http://localhost:58427/api/Values?api-version=2.0

三、經過http請求的 Headers 來控制,接口地址不變,下邊會說到 

四、利用 content type 來控制 

 

老張:本文只是一個說明版本,並無把全部的方案都 code 出來,重點說了下路由控制,剩下的只是引導你們去思考這個問題,而後繼續學習,畢竟會一兩個方法就好了,平時開發中,使用的並非很頻繁,有好的想法歡迎下邊留言,或者來羣裏和咱們的小夥伴熱情互動吧!

 

1、在 swagger 中經過路由實現版本控制

一、註冊多個版本api

一、在 Blog.Core 項目下新建 SwaggerHelper 文件夾,而後添加 CustomApiVersion.cs 用來控制版本

 

二、在自定義API版本類中,添加枚舉版本號

/// <summary>
    /// 自定義版本
    /// </summary>
    public class CustomApiVersion
    {
        /// <summary>
        /// Api接口版本 自定義
        /// </summary>
        public enum ApiVersions
        {
            /// <summary>
            /// v1 版本
            /// </summary>
            v1 = 1,
            /// <summary>
            /// v2 版本
            /// </summary>
            v2 = 2,
        }
    }

 

三、在項目啓動類 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" }
    });
});

 

 四、修改 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}");
    });
});

 

五、查看效果

如今已經實現了,在 swagger 中,進行多版本的展現,那要如何進行控制呢,請往下看。

 

二、對接口進行版本配置

一、剛剛咱們已經建立好了多版本的接口文檔,那如今就須要配置接口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 ,下邊的文章中會說到,若是必定要重名,須要怎麼作。

 

二、這個時候查看效果,發現已經實現了咱們文件開頭的效果

 

 這個時候效果已經實現了,可是這麼寫顯然不是很方便,首先,咱們的組名 GroupName 是寫死的 」v2「,不利用拓展,而後呢,還須要再一次配置路由 Route,有小夥伴就發現了,既然這兩個都是特性,有沒有辦法重寫一個特性,把這兩個合併呢,欸?!就是這樣,請往下看。

 

三、自定義路由特性,實現路由+版本 雙控制

一、在根目錄的 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();
        }
    }

 

二、對 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接口版本控制已經說完了,採用的方法是路由控制,我我的感受仍是挺好的,固然文章的開頭也說到了,仍是有其餘的方法,這裏就簡單的其中一個,我的不是很推薦,可是你們能夠看看。

2、同名接口的版本控制

在上邊我們說到了,若是兩個版本的方法名必定要一直咋辦呢,重載你們確定都知道,可是同一個 controller 接口方法確定不管參數仍是名稱所有都同樣,就連返回類型也同樣,因此不能重載,那咱們應該怎麼辦呢?,請往下看。

 

一、 在 controller 文件夾下,新建兩個文件夾, v一、v2

二、而後添加相同的接口控制器 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

 

 

4、Github

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

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

相關文章
相關標籤/搜索