最近在做微服务的时候,由于我们是采用前后端分离来开发的,提供给前端的直接是Swagger,如果Swagger分布在各个API中,前端查看Swagger的时候非常不便,因此,我们试着将Swagger集中放到网关中。
这里我用两个API项目(一个BasicDataApi,一个UsersApi)和一个网关项目(ApiGateway)做示例,下面直接上代码。
首先在BasicDataApi中配置Swagger:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSwaggerGen(options => { options.SwaggerDoc("BasicDataApi", new Info { Title = "基础数据服务", Version = "v1" }); var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "Qka.BasicDataApi.xml"); options.IncludeXmlComments(xmlPath); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseMvc() .UseSwagger(c => { c.RouteTemplate = "{documentName}/swagger.json"; }) .UseSwaggerUI(options => { options.SwaggerEndpoint("/BasicDataApi/swagger.json", "BasicDataApi"); }); }
在UsersApi中一样的配置:
public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(options => { options.SwaggerDoc("UsersApi", new Info { Title = "用户API接口", Version = "v1" }); var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "Qka.UsersApi.xml"); options.IncludeXmlComments(xmlPath); }); services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseMvc() .UseSwagger(c => { c.RouteTemplate = "{documentName}/swagger.json"; }) .UseSwaggerUI(options => { options.SwaggerEndpoint("/UsersApi/swagger.json", "UsersApi"); }); }
最后在网关项目中修改Ocelot配置,获取两个项目的swagger.json不要授权:
"ReRoutes": [ { "DownstreamPathTemplate": "/UsersApi/swagger.json", "DownstreamScheme": "http", "ServiceName": "userapi", "LoadBalancer": "RoundRobin", "UseServiceDiscovery": true, "UpstreamPathTemplate": "/UsersApi/swagger.json", "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ] }, { "DownstreamPathTemplate": "/BasicDataApi/swagger.json", "DownstreamScheme": "http", "ServiceName": "basedataapi", "LoadBalancer": "RoundRobin", "UseServiceDiscovery": true, "UpstreamPathTemplate": "/BasicDataApi/swagger.json", "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ] }, { "DownstreamPathTemplate": "/UsersApi/{url}", "DownstreamScheme": "http", "ServiceName": "userapi", "LoadBalancer": "RoundRobin", "UseServiceDiscovery": true, "UpstreamPathTemplate": "/UsersApi/{url}", "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ] , "AuthenticationOptions": { "AuthenticationProviderKey": "qka_api", "AllowedScopes": [] } } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:9000", "ServiceDiscoveryProvider": { "Host": "192.168.2.144", "Port": 8500 } } }
修改StartUp.cs文件的代码,注意在使用中间件的时候,UseMvc一定要在UseOcelot之前。
:
public void ConfigureServices(IServiceCollection services) { services.AddOcelot(); var authenticationProviderKey = "qka_api"; services.AddAuthentication("Bearer") .AddIdentityServerAuthentication(authenticationProviderKey, options => { options.Authority = "http://192.168.2.121:9066/"; options.RequireHttpsMetadata = false; options.ApiName = "UserApi"; }); services.AddMvc(); services.AddSwaggerGen(options => { options.SwaggerDoc("ApiGateway", new Info { Title = "网关服务", Version = "v1" }); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMetricsAllMiddleware(); app.UseMetricsAllEndpoints(); app.UseCors("default"); var apis = new List<string> { "BasicDataApi", "UsersApi" }; app.UseMvc() .UseSwagger() .UseSwaggerUI(options => { apis.ForEach(m => { options.SwaggerEndpoint($"/{m}/swagger.json", m); }); }); app.UseOcelot().Wait(); }
最后上图: