- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
公司项目是是微服务项目,网关是手撸的一个.net core webapi 项目,使用 refit 封装了 20+ 服务 SDK,在网关中进行统一调用和聚合等处理,以及给前端提供 swagger 文档 在我两年前进公司的时候,文档还能够顺滑的打开,在去年的时候文档只能在本地打开,或者访问原始的 swagger 页面,knife4j 的页面更是打不开一点,于是想办法对此进行了优化 。
首先再记录一下安装及使用,之前也分享过 Swashbuckle.AspNetCore 的使用,不过版本比较老了,本次演示用的示例版本为 .net core 8.0,从安装使用开始分享一二 。
<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
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);
});
}
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 就从慢,到打开超时偶尔能打开,到每次都打不开(/api-docs 过大返回超时,渲染卡顿) 这个时候,或者一开始就应该对 swagger 进行分组返回了,优化 /api-docs 接口返回的数据 当然,除了这种方式,还有可以加特效标记的方式,但是几百个服务,加不了一点 。
一开始并没有想到分组显示,因为在本地运行的时候是可以打开的,只是 json 文件较大,于是做了一个优化是每次在发布应用后,请求一个接口去将 swagger 的 json 文件生成到本地,后续访问直接读取,算是暂时解决了打不开的问题,这样用了大半年,实在受不了这个速度,然后平时在看一些开源项目的时候发现是完全可以按自己的规则进行分组的,于是有了这篇文章 。
为了兼容之前的文档路由,所以还是在原有配置的基础上,配置了其他模块的接口文档 可有两种方式 。
//设置需要分组的api接口
var groupApis = new List<string>() { "SwaggerTest.Controllers.Test", "SwaggerTest.Controllers.Demo" };
//配置文档信息
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;
});
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())
}
};
})
修改完成后,可以结合自己业务来定义需要单独显示分组,最近又基于此加了一个开放平台的接口,独立于正常网关,单独提供出去,一切都是刚刚好~ 。
如果有更好的方式,欢迎分享 若有错误,欢迎指出,谢谢 。
最后此篇关于基于.netcore8.0的swagger文档优化分享-根据命名空间分组显示的文章就讲到这里了,如果你想了解更多关于基于.netcore8.0的swagger文档优化分享-根据命名空间分组显示的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
运行 Tomcat 失败并出现 java.lang.OutOfMemoryError - 与缺少 PermGen 空间相关的错误。 我最近将 Tomcat 更改为以自己的用户(而非 root)运行。
我们有一个表,其中包含数百万行,其中包含 PostGIS 几何图形。我们要执行的查询是:落在边界几何内的最新条目是什么?这个查询的问题是我们经常会有大量的项目匹配边界框(半径大约为 5 公里),然后
我有一个Elasticsearch设置,它将允许用户搜索通配符作为索引。 array:3 [ "index" => "users" "type" => "user" "body" => arra
我创建了一个表,其中每行包含两个按钮,并且两个按钮连接在一起,我想将两个按钮分开。我用过 不起作用,css 也是,这是他们的另一种方式。 我有另一个问题,因为我不想在表格边框内显示操作按钮,而是在靠近
我试图在 jQuery Mobile 中的两个按钮之间留出空白。现实中的布局是这样的: Button 1 Button 2 (Hidden w/ display: none)
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
您好,我对图表应用程序还很陌生。现在我为我的应用程序创建了条形图。当我运行 create bar chart as separate project 时,输出如下所示。 然后当我将条形图与我的应用程序
我在使用 H2 和 GeoDB(内存中,junit)时遇到问题。 另外,使用 Hibernate 5(每个包的最新版本,包括 hibernate-spatial)和 Spring 4。 通过 id 实
我想画一张澳大利亚的 map ,并将每个城市表示为一个点。 然后突出显示人口众多(> 1M)的城市 library(sp) library(maps) data(canada.cities) head
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 6年前关闭。 Improve this
如何保持.txt文件中存在的空格?在.txt文件中,它表示: text :text text1 :text1 text23 :text2 text345 :text3 如果我写这段
以下哪个键最大? 选项 1:16 个数字 [0,9] 选项 2:30 个元音 选项 3:字母表中的 16 个字母 选项 4:32 位 有人可以帮助我,告诉我哪一个是正确的答案以及我们如何计算它吗?我知
在 Unity 3d 中使用 Azure 空间 anchor 来实现在 iOS 和 Android 上部署的室内和室外增强现实体验是否有益? 最佳答案 是的,对于 Azure Spatial Anch
我有一个绝对定位的圆形图像。图像只需占据屏幕宽度的 17%,并且距离顶部 5 个像素。 问题是,当我调整图像大小以占据屏幕宽度的 17% 时,它会这样做,但同时容器会变长。图像本身不会拉伸(stret
我在 Ubuntu 14.04 上使用 Cassandra。从文档中,我可以看到运行命令: nodetool snapshot 创建我的 key 空间的快照。 命令的输出是: nodetool sn
Heroku引入了“私有(private)空间”,是否可以将现有应用迁移到私有(private)空间? https://blog.heroku.com/archives/2015/9/10/herok
是否允许在语义记录中使用非绑定(bind)空格 或其他 HTML 编码字符?我遇到的问题是 ; 字符被软件视为记录的结尾。 例如:假设我有一份婚姻记录,其中包含 2 个结婚者的姓氏、结婚年份以及结
我正在研究“智能 parking ”项目,偶然发现了包含我们真正需要的YouTube视频。我们已经实现了第一部分,即从视频源进行实时透视变换,下一步是将其定义为一组矩形 我基本上需要知道他是如何做到的
我有两个类:Engine 和 Trainset(多个单元),这两个类共享其 ID 空间,其中包含名称和系列 id=- . 这是我的Engine类(它是抽象的,因为有引擎的子类型(DieselEngin
如果有人能帮助我,那就太好了。 我正在尝试使用Java的Split命令,使用空格分割字符串,但问题是,字符串可能没有空格,这意味着它将只是一个简单的顺序(而不是“输入2”将是“退出”) Scanner
我是一名优秀的程序员,十分优秀!