前言

公司项目是是微服务项目,网关是手撸的一个.net core webapi 项目,使用 refit 封装了 20+ 服务 SDK,在网关中进行统一调用和聚合等处理,以及给前端提供 swagger 文档

在我两年前进公司的时候,文档还能够顺滑的打开,在去年的时候文档只能在本地打开,或者访问原始的 swagger 页面,knife4j 的页面更是打不开一点,于是想办法对此进行了优化

.net core 项目中使用 Swashbuckle.AspNetCore 生成 SwaggerUI

首先再记录一下安装及使用,之前也分享过 Swashbuckle.AspNetCore 的使用,不过版本比较老了,本次演示用的示例版本为 .net core 8.0,从安装使用开始分享一二

安装包

  • 新建.net core 项目
  • 添加 Swashbuckle.AspNetCore 相关包引用
  • 设置项目 xml 生成路径,组件将根据 xml 解析接口相关信息
  <ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.6.2" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.2" />
</ItemGroup>
<PropertyGroup>
<DocumentationFile>bin\$(MSBuildProjectName).xml</DocumentationFile>
</PropertyGroup>

服务配置

  • 一些基础配置使用备忘

    • 配置文档信息 c.SwaggerDoc
    • 配置环境 c.AddServer
    • 配置模型标识 c.CustomSchemaIds
    • 配置唯一标识 c.CustomOperationIds
    • 配置解析 xml c.IncludeXmlComments
    • 启用数据注解 c.EnableAnnotations [SwaggerOperation]
  • 完整配置如下
//框架初始化巴拉巴拉xxx
builder.Services.AddControllers();
//配置 swagger
UseSwagger(builder.Services); /// <summary>
/// Swagger 注入配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
void UseSwagger(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
//配置文档信息
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "swagger接口文档测试",
Description = "这是一个文档",
Version = "v1",
});
//配置环境
c.AddServer(new OpenApiServer()
{
Url = "",
Description = "本地"
});
//配置模型标识,默认type.Name,名称一样,不同明明空间会报错,所以改成FullName,加上命名空间区分
c.CustomSchemaIds(type => type.FullName);
//配置唯一标识
c.CustomOperationIds(apiDesc =>
{
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
});
//解析站点下所有xml,一般加自己项目的引用的即可
foreach (var file in Directory.GetFiles(AppContext.BaseDirectory, "*.xml"))
{
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, file));
}
//启用数据注解
c.EnableAnnotations(true, true);
});
}
  • 启用 swagger

RunSwagger(app); /// <summary>
/// 启用swagger
/// </summary>
/// <param name="app"></param>
void RunSwagger(IApplicationBuilder app)
{
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/v1/api-docs", "V1 Docs");
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapSwagger("{documentName}/api-docs");
endpoints.MapGet("/v3/api-docs/swagger-config", async (httpContext) =>
{
JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
IgnoreNullValues = true
};
jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, false));
SwaggerUIOptions _options = new SwaggerUIOptions()
{
ConfigObject = new ConfigObject()
{
Urls = new List<UrlDescriptor>
{
new UrlDescriptor()
{
Url="/v1/api-docs",
Name="V1 Docs"
}
}
}
};
await httpContext.Response.WriteAsync(JsonSerializer.Serialize(_options.ConfigObject, jsonSerializerOptions));
});
});
}

运行

  • 运行后可以看到配置成功,swagger文档已经生成

到这里基础的 swagger 配置已可以使用,更深层次的参考官方文档使用即可,接下来才是不一样的东西

随着我们的项目发展,当我们的服务越来越多,接口也越来越多的时候,swagger 就从慢,到打开超时偶尔能打开,到每次都打不开(/api-docs 过大返回超时,渲染卡顿)

这个时候,或者一开始就应该对 swagger 进行分组返回了,优化 /api-docs 接口返回的数据

当然,除了这种方式,还有可以加特效标记的方式,但是几百个服务,加不了一点

分模块返回文档

一开始并没有想到分组显示,因为在本地运行的时候是可以打开的,只是 json 文件较大,于是做了一个优化是每次在发布应用后,请求一个接口去将 swagger 的 json 文件生成到本地,后续访问直接读取,算是暂时解决了打不开的问题,这样用了大半年,实在受不了这个速度,然后平时在看一些开源项目的时候发现是完全可以按自己的规则进行分组的,于是有了这篇文章

为了兼容之前的文档路由,所以还是在原有配置的基础上,配置了其他模块的接口文档

可有两种方式

  • 一种是在原有基础上显示其他分组

  • 一种是单独的 swagger 进行显示



优化修改

  • 先定义好需要分组显示的模块
//设置需要分组的api接口
var groupApis = new List<string>() { "SwaggerTest.Controllers.Test", "SwaggerTest.Controllers.Demo" };
  • UseSwagger 修改部分
  • 重点是这块的自定义,去分组中匹配路由 c.DocInclusionPredicate 官方文档
//配置文档信息
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "swagger接口文档测试",
Description = "这是一个文档",
Version = "v1",
});
//配置环境
c.AddServer(new OpenApiServer()
{
Url = "",
Description = "本地"
});
//模型标识配置,默认type.Name,名称一样,不同明明空间会报错,所以改成FullName,加上命名空间区分
c.CustomSchemaIds(type => type.FullName);
c.CustomOperationIds(apiDesc =>
{
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
});
//加载注释文件
foreach (var file in Directory.GetFiles(AppContext.BaseDirectory, "*.xml"))
{
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, file));
}
//增加模块接口的注册
groupApis.ForEach(s =>
{
c.SwaggerDoc(s, new OpenApiInfo
{
Title = "api-" + s,
Description = "api " + s,
Version = "v1",
});
}); //启用数据注解
c.EnableAnnotations(true, true);
//自定义分组匹配
c.DocInclusionPredicate((docName, apiDes) =>
{
if (groupApis.Contains(docName))
{
var displayName = apiDes.ActionDescriptor?.DisplayName?.ToLower() ?? string.Empty;
var existGroup = groupApis.FirstOrDefault(s => displayName.Contains(s.ToLower()));
return docName == existGroup;
} return true;
});
  • RunSwagger 修改部分
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/v1/api-docs", "V1 Docs");
//默认页支持分组
groupApis.ForEach(s =>
{
c.SwaggerEndpoint($"/{s}/api-docs", s);
});
});
//单独的页面
groupApis.ForEach(s =>
{
app.UseSwaggerUI(c =>
{
c.RoutePrefix = s;
c.SwaggerEndpoint($"/{s}/api-docs", s);
});
});
app.UseEndpoints(endpoints =>
{
SwaggerUIOptions _options = new SwaggerUIOptions()
{
ConfigObject = new ConfigObject()
{
Urls = new List<UrlDescriptor>
{
new UrlDescriptor()
{
Url="/v1/api-docs",
Name="V1 Docs"
}
}.Concat(groupApis.Select(s => new UrlDescriptor()
{
Url = $"/{s}/api-docs",
Name = s
}).ToList())
}
};
})

修改完成后,可以结合自己业务来定义需要单独显示分组,最近又基于此加了一个开放平台的接口,独立于正常网关,单独提供出去,一切都是刚刚好~

后语

如果有更好的方式,欢迎分享

若有错误,欢迎指出,谢谢

相关文档

基于 .net core 8.0 的 swagger 文档优化分享-根据命名空间分组显示的更多相关文章

  1. asp.net core web api 生成 swagger 文档

    asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果 ...

  2. asp.net core 2.1 生成swagger文档

    新建asp.netcore2.1 api项目 “WebApplication1” 在nuget管理器中添加对Swashbuckle.AspNetCore 3.0.0.Microsoft.AspNetC ...

  3. ASP.NET CORE 1.0 MVC API 文档用 SWASHBUCKLE SWAGGER实现

    from:https://damienbod.com/2015/12/13/asp-net-5-mvc-6-api-documentation-using-swagger/ 代码生成工具: https ...

  4. 基于.net core 2.0+mysql+AceAdmin搭建一套快速开发框架

    前言 .net core已经出来一段时间了,相信大家对.net core的概念已经很清楚了,这里就不再赘述.笔者目前也用.net core做过一些项目,并且将以前framework下的一些经验移植到了 ...

  5. 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架 - LinFx

    LinFx 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架,遵循领域驱动设计(DDD)规范约束,提供实现事件驱动.事件回溯.响应式等特性的基础设施.让开发者享受到正真意义的面向对象 ...

  6. 基于WPF系统框架设计(5)-Ribbon整合Avalondock 2.0实现多文档界面设计(二)

    AvalonDock 是一个.NET库,用于在停靠模式布局(docking)中排列一系列WPF/WinForm控件.最新发布的版本原生支持MVVM框架.Aero Snap特效并具有更好的性能. Ava ...

  7. Core + Vue 后台管理基础框架8——Swagger文档

    1.前言 作为前后端分离的项目,或者说但凡涉及到对外服务的后端,一个自描述,跟代码实时同步的文档是极其重要的.说到这儿,想起了几年前在XX速运,每天写完代码,还要给APP团队更新文档的惨痛经历.给人家 ...

  8. Swagger文档转Word 文档

    GitHub 地址:https://github.com/JMCuixy/SwaggerToWord/tree/developer 原创作品,转载请注明出处:http://www.cnblogs.co ...

  9. 使用 Swagger 文档化和定义 RESTful API

    大部分 Web 应用程序都支持 RESTful API,但不同于 SOAP API——REST API 依赖于 HTTP 方法,缺少与 Web 服务描述语言(Web Services Descript ...

  10. 使用.NET 6开发TodoList应用(27)——实现API的Swagger文档化

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在日常开发中,我们需要给前端提供文档化的API接口定义,甚至需要模拟架设一个fake服务用来调试接口字段.或者对于后端开发人员 ...

随机推荐

  1. htts证书申请

    https://freessl.cn/ 教程: https://www.bilibili.com/video/BV1Ug411673P/?spm_id_from=333.337.search-card ...

  2. GPS坐标、火星坐标、百度坐标之间的转换--提供java版本转换代码

    参考文章:https://www.jianshu.com/p/c39a2c72dc65?from=singlemessage 1.国内几种常用坐标系说明 (1)名词解释 坐标系统:用于定位的系统,就跟 ...

  3. C语言:Hello Word(梦开始的地方)

    #include <stdio.h>//标准输入输出头文件,下面的printf打印的函数包含在这个头文件里面 int main() { printf("Hello Word!&q ...

  4. 线程中使用for循环的add或remove方法的两种方案

    简介 (Introduction): 背景 在使用线程中添加list的元素时,使用add或remove就会产生异常. 分析 该list每当删除/添加一个元素时,集合的size方法的值都会减小1,这将直 ...

  5. PageOffice 6 给SaveFilePage指向的保存地址传参

    PageOffice给保存方法传递参数的方式有两种: 通过设置保存地址的url中的?传递参数.例如: poCtrl.setSaveFilePage("/save?p1=1") 通过 ...

  6. efcore如何优雅的实现按年分库按月分表

    efcore如何优雅的实现按年分库按月分表 介绍 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖. ...

  7. .NET8 Identity Register

    分享给需要帮助的人:记一次 IdentityAPI 中注册的源码解读:设置用户账户为未验证状态,以及除此之外更安全的做法: 延迟用户创建.包含了对优缺点的说明,以及适用场景. 在ASP.NET 8 I ...

  8. debug技巧之使用Arthes调试

    一.前言 大家好啊,我是summo,今天给大家分享一下我平时是怎么调试代码的,不是权威也不是教学,就是简单分享一下,如果大家还有更好的调试方式也可以多多交流哦. 前面我介绍了本地调试和远程调试,今天再 ...

  9. C# 使用 NPOI 导出excel 单击单元格背景变黑色的解决办法

    需要手动指定单元格的背景色为一种颜色, 特别注意,我在使用 var color=new XSSFColor(new color...)创建的颜色,即使设置成其他颜色,查看样式属性中,发现color.i ...

  10. Mybatis-Plus update不存在的数据返回值一定为零?

    MP update不存在的数据返回值一定为零? 本文分为以下几个部分: 前言 验证过程 结论 前言 ​ MP(mybatis-plus),在 MyBatis 的基础上只做增强不做改变,为简化开发.提高 ...