本来不想写这一篇的,swagger是很常用的,节省了不少写文档的时间,这也并不是什么新鲜玩意,使用起来也很简单。但是如果加入了ocelot网关,那么问题来了,如何能访问到底层服务的 API接口呢?
单应用
安装依赖包
PM> Install-Package Swashbuckle.AspNetCore
appsettings.json文件中加上一些配置信息
"Service": {
"Name": "Api01"//Consul中注册的服务名
},
"Swagger": {
"IsActive": true,//是否开启Swagger
"Version": "v1.0",//版本号
"Description": "Api01服务接口清单"//描述
}
修改ConfigureServices
services.AddSwaggerGen(c =>
{
c.SwaggerDoc(Configuration["Swagger:Version"],
new OpenApiInfo
{
Title = Configuration["Service:Name"],
Version = Configuration["Swagger:Version"],
Description = Configuration["Swagger:Description"]
});
var xmlFile = "CustomMiddleware.api01.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
修改Configure,加上如下代码
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/" + Configuration["Swagger:Version"] + "/swagger.json", Configuration["Service:Name"]);
});
修改项目属性,导出xml,可以自动加上注释信息

运行结果
打开http://localhost:5000/swagger/index.html,如下图示:

微服务架构下
当我们加上网关之后,虽然接口可以正常访问,但是打开swagger/index.html就不行了,我们就不能直接访问了,如下图:

其实也很好理解,提示找不到json文件/swagger/v1.0/swagger.json。经过网关转发之后,前面必须要加上服务名称的前缀才可以访问到。
根据这个思路,如果我们把网关的项目上重新绑定下SwaggerEndpoint就可以了。
开干吧!
网关项目加上Swashbuckle.AspNetCore依赖包,过程和上面一样
PM> Install-Package Swashbuckle.AspNetCore
修改ConfigureServices
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1.0", new OpenApiInfo()
{
Title = "网关服务",
Version = "v1"
});
});
其实这一段加不加无所谓,因为我的网关项目也有自己的接口,所以加上网关自身的API也是可行的。
修改Configure方法,加上以下代码
//获取consul上的所有服务,为其加上Swagger文档
ConsulClient consulClient = new ConsulClient(x => x.Address = new Uri("http://192.168.10.134:8500"));
var services = consulClient.Agent.Services().Result.Response.Values;
var apis = services.ToList().Select(t => t.Service).ToList();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1.0/swagger.json", "ApiGateway");
//加载consul服务中的api文档
apis.ForEach(m =>
{
options.SwaggerEndpoint($"/{m}/swagger/v1.0/swagger.json", m);
});
});
这里才是关键,我们通过conusl客户端获取服务的名称列表,然后遍历依次添加到swaggerEndpoint中去,此时我们把服务名称加到路径的最前面,这样网关就会根据服务名转到相应的下游地址。并且可以在浏览器中切换不同服务的接口文档了。
测试
下图是可以切换不同服务的。

切换到Api01的文档

完美切换过来了,大功告成了,不过这里有点坑,就是需要获取conusl的服务,不知道各位大佬有没有其他更好的方式呢?
其实文档一般不会暴露出去可以配合授权模块加上授权验证,以免暴露接口。




