WebApi + Swagger2.0接口文档多版本控制设计实现

最近前后端分离的项目越来越多,API的对接对于前后端开发交流得最多的一块内容,一个好的API文档生成工具就显得非常重要,选取了Swagger文档生成工具作为项目的文档生成工具,考虑到多版本的文档生成,基于swagger5.6版本实现了一套多版本控制

1.  NuGet包引用

比较简单,下面三个包都引用,删掉自动生成的页面文件,本此介绍多版本此处省略NuGet引入的文件清理工作了

2. 多版本控制

找到App_Start文件夹下面的SwaggerConfig,找到下图的节点,默认是c.SingApiVersion生效,先注释此行,再打开c.MultipleApiVersions勾子节点

此处有一个匿名方法调用ResolveVersionSupportByRouteConstraint,此方法需要自己实现,其中apiDesc是当前工程文件实现ApiController的全部路由数据,targetApiVersion是当前版本信息,直接在SwaggerConfig类中生成私有方法,我的实现如下,思路是在此处过滤掉非当前版本的Controller路由

 private static bool ResolveVersionSupportByRouteConstraint(ApiDescription apiDesc, string targetApiVersion)
{
//过滤由多版本的controller带来的重复route注册api desc,按命名空间的版本信息过滤,只返回版本内的api
return apiDesc.ActionDescriptor.ControllerDescriptor.ControllerType.FullName.ToLower().Contains(string.Format(".{0}.", targetApiVersion));
}

3. 路由文件版本分离规则

注意工程文件中Controllers的版本是通过命名空间隔离的,上面的代码就是通过版本信息来匹配这个命名空间来实现过滤,假设v1和v2文件夹中都有ValuesController

两个版本的ValuesController如下,route在Map时不能有重复名称的Controller,所以此处采取加上版本,v1不需要添加,v2的ValuesController上加上版本, 借助RoutePrefix为ValuesV2Controller重写路由,对外路由统一为api/{verstion}/Values并不会有ValuesV2出现在api路由上,此处的ValuesV2在文档生成时还需要特殊处理,下面会重点提到IDocumentFilter接口实现时的处理

4. 多版本路由注册

此时在WebApiConfig的路由注册中写下如下代码,分别注册两个版本的路由对应v1,v2版本

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/{controller}/{id}",
defaults: new { id = RouteParameter.Optional}
); config.Routes.MapHttpRoute(
name: "Apiv2",
routeTemplate: "api/v2/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

5. IDocumentFilter接口实现

多版本的控制到这就算基本实现了,只不过ValuesV2这个路由的文档中依然会带上这个V2, 由于我们在RoutePrefix中已经配置了V2的Values路由是api/v2/Values,但按路由注册规则文档生成的路由默认会是api/v2/ValuesV2, 如果按文档生成的路径调用时会报找不到文件,原因就是RoutePrefix生效的路由与Swagger文档路由不匹配,好在Swagger提供的过滤接口能帮助我们自定义过滤规则,在SwaggerConfig中找到如下节点,打开注释,其中ApplyDocumentVendorExtensions需要我们自己实现

c.DocumentFilter<ApplyDocumentVendorExtensions>();

实现IDocumentFilter接口的ApplyDocumentVendorExtensions文档处理类

internal class ApplyDocumentVendorExtensions : IDocumentFilter
{
/// <summary>
/// //swagger版本控制过滤
/// </summary>
/// <param name="swaggerDoc">文档</param>
/// <param name="schemaRegistry">schema注册</param>
/// <param name="apiExplorer">api概览</param>
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
//缓存目标路由api
IDictionary<string, PathItem> match = new Dictionary<string, PathItem>();
//取版本
var version = swaggerDoc.info.version;
foreach (var path in swaggerDoc.paths)
{
//过滤命名空间 按名称空间区分版本
if (path.Key.Contains(string.Format("/{0}/", version)))
{
//匹配controller descript中的版本信息
Regex r = new Regex("/\\w+" + version, RegexOptions.IgnoreCase);
string newKey = path.Key;
if (r.IsMatch(path.Key)) {
var routeinfo = r.Match(path.Key).Value;
//修正controller别名路由符合RoutePrefix配置的路由 如api/v2/ValuesV2 修正为 api/v2/Values
newKey = path.Key.Replace(routeinfo, routeinfo.Replace(version.ToLower(), "")).Replace(
routeinfo, routeinfo.Replace(version.ToUpper(), ""));
}
//保存修正的path
match.Add(newKey, path.Value);
}
}
//当前版本的swagger document
swaggerDoc.paths = match;
}
}

至此多版本控制就实现了,其中要注意的地方是Controllers下的V1,V2文件夹下的Controller文件的命名空间要保持默认命名空间,效果如下

ValuesV2请求的实际路由已修正

有部分朋友询问SwaggerConfig中的勾子方法使用,本文重点在搭建SwaggerConfig在线文档和多版本实现,勾子方法推荐使用的几个方法下面简单介绍下:

开启数据模型注释在文档中生成,参数为当前应用程序依赖的数据模型程序集名称,GetXmlPath自己实现

c.IncludeXmlComments(GetXmlPath("DataModel"));

//控制器描述Provider,Swagger提供了ISwaggerProvider接口,供自定义实现控制器的描述在文档中的生成,CachingSwaggerProvider需要自己实现ISwaggerProvider接口

c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));

//Action相关描述

c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());

Swagger接口文档页面中的label汉化js文件,来源网络

c.InjectJavaScript(thisAssembly, "WebApi.Scripts.Swagger-Custom.js");

有可运行的demo没找到地方上传,欢迎索取

                                                                           --晴天的故事

WebApi的Swagger多版本控制实现的更多相关文章

  1. ASP.NET WebAPI使用Swagger生成测试文档

    ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...

  2. ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

    引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...

  3. .NetCore2.1 WebAPI 根据swagger.json自动生成客户端代码

    前言 上一篇博客中我们可以得知通过Swagger插件可以很方便的提供给接口开发者在线调试,但是实际上Swagger附带的功能还有很多, 比如使用NSwag生成客户端调用代码,进一步解放接口开发者. N ...

  4. ASP.NET Core WebApi使用Swagger生成api

    引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...

  5. ASP.NET WebAPI 集成 Swagger 启用 OAuth 2.0 配置问题

    在 ASP.NET WebAPI 集成 Swagger 后,由于接口使用了 IdentityServer 做的认证,调试起来很不方便:看了下 Swashbuckle 的文档 ,是支持 OAuth2.0 ...

  6. ASP.NET Core WebApi使用Swagger生成api说明文档

    1. Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件 ...

  7. C# ABP WebApi与Swagger UI的集成

    本文是配置WebApi与Swagger UI,可以参照 http://www.cnblogs.com/farb/p/ABPSwaggerUIIntegration.html 1. 安装swagger ...

  8. Asp.net WebApi 配置 Swagger UI

    首先安装Swashbuckle.Core 然后添加swagger配置文件. [assembly: PreApplicationStartMethod(typeof(SwaggerConfig), &q ...

  9. 【转】ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

    原文链接:https://www.cnblogs.com/yilezhu/p/9241261.html 引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必 ...

随机推荐

  1. 机器学习中python的有关使用技巧【创建虚拟环境、jupyter的kernel修改】

    1.创建虚拟环境<在原来基础上建立> *注:(这里是python2.python3环境共存,我要创建一个python3的虚拟环境) 一.先安装虚拟环境变量: pip3 install -U ...

  2. VMProtect使用小计【二】 – 加壳查看

    Release 我这里使用的是Release的版本,Debug的版本分析没有多少的必要,因为程序发布过之后就是Release的,我们先看一下这个文件 原程序分析 使用OD打开VMProtectDemo ...

  3. ebay上传图片的要求

    eBay's Picture Requirements Introduction to Pictures in Listings Pictures make an item more appealin ...

  4. HTML5自定义属性的设置与获取

    <div id="box" aaa="bbb" data-info="hello"></div> <body& ...

  5. 6. Python运算符之算术、比较、赋值运算符

    什么是运算符?举个简单的例子 4 +1 = 5 . 例子中,4 和 1 被称为操作数,"+" 和"="称为运算符. 工作中用到的运算符主要有以下几种:算术运算符 ...

  6. ThreadLocal浅析

    1.ThreadLocal的大体理解 ThreadLocal 又名 线程局部变量,是 Java 中一种较为特殊的 线程绑定机制,可以为每一个使用该变量的线程都提供一个变量值的副本,并且每一个线程都可以 ...

  7. 数据挖掘Aprior算法详解及c++源码

    [算法大致描述] Aprior算法主要有两个操作,扫描数据库+统计.计算每一阶频繁项集都要扫描一次数据库并且统计出满足支持度的n阶项集. [算法主要步骤] 一.频繁一项集 算法开始第一步,通过扫描数据 ...

  8. java-day02

    数据类型自动转换 要求:数据范围从小到大 数据类型强制类型转换 格式:范围小的数据类型 范围小的变量名 = (范围小的数据类型)原范围大的数据 注意事项: 1.可以会造成数据溢出或者是精度损失. 2. ...

  9. 问题1-/usr/bin/python: No module named virtualenvwrapper

    操作系统:Ubuntu 问题:创建虚拟环境时,出现:/usr/bin/python: No module named virtualenvwrapper 解决方法: 1.切换到用户家目录 2.打开隐藏 ...

  10. spring boot Swagger2(version=2.7.0) 注解@ApiImplicitParam的属性dataType值为”自定义泛型“应用

    注解: @ApiImplicitParams @ApiImplicitParam    name="需注解的API输入参数", value="接收参数的意义描述" ...