1, Introduction
When we develop microservice based applications, we can't skip one link, that is to create WebApi, and then our applications are accessed based on WebApi interface. Before Swagger, we developed the Web API interface and had to write a lot of interface documents. Can't you write? Of course not. If you don't write these documents, how can others use your interface? Should every interface communicate with the person who writes the interface? Then the communication cost is too large and unnecessary time is wasted. After we have Swagger, we only need to configure it simply to generate detailed documents about the interface, and it can be called and executed, which saves a lot of effort for users and developers.
However, we now have a problem. In our solution, there are multiple WebApi instance programs, and each API instance program is configured with its own Swagger for ease of use. However, there is another problem. We have multiple API instance programs, and each instance Program corresponds to a Swagger program. What should we do when we want to access it? Many people will say that you can open whichever Swagger program you visit. Of course, if you are not afraid of tedious, you can do so. Since it is so cumbersome, others must have encountered it. There must be a corresponding solution to this problem.
Speaking of solutions, in fact, we can easily remember. We create a public web API based Gateway project. In this gateway project, we configure Swagger, and then access the Swagger of each API instance program by accessing the Swagger of the gateway.
2, Start us
Without much nonsense, let's start today's configuration and demonstration. There are only a few projects in this solution. There are three WEB API projects, all of which are based on Net 5.0 and can cross platform. In this solution, because we want to use service discovery and gateway configuration, we need to introduce Consul, Swashbuckle.AspNetCore, Ocelot and Ocelot.Provider.Consul into each required project. The specific operations are as follows:
1. Preparation.
Before we start our project, we need to consult now. The 64 bit version of windows I downloaded here is tested. If it is in the production environment, we can download the Linux version as needed.
Download address: https://www.consul.io/downloads
The command to start Consul service is also very simple. In the download directory, enter cmd in the address bar and open the command window. Then enter the command: consumer agent - dev. The screenshot is as follows:
2. Project source code
1]. The first WABAPI instance program.
(1) screenshot of the project
(2) project source code
Since the project uses Consul for service discovery management, at the beginning of the project creation, the Consul component must be installed through Nuget. At the same time, Swashbuckle.AspNetCore must be introduced, which supports the implementation of Swagger.
A. create a WebAPI project with the name of Patrick liu.microservice.weixin.userservice.
B. the Consul and Swashbuckle.AspNetCore component packages are introduced through Nuget respectively.
C. extend the Consul service and create one under the root directory Utilities file and create a class: ConsulManager.cs under this folder
1 using Consul; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.Extensions.Configuration; 4 using System; 5 6 namespace PatrickLiu.MicroService.WeiXin.UserService.Utilities 7 { 8 /// <summary> 9 /// This type extends IApplicationBuilder Type for implementing Consul The work of service registration. 10 /// </summary> 11 public static class ConsulManager 12 { 13 /// <summary> 14 /// Extension method, implementation WebApi Service registration Consul Center. 15 /// </summary> 16 /// <param name="app">Application builder.</param> 17 /// <param name="configuration">Configure the access type of the system.</param> 18 /// <param name="consulClient">Consul The client type of the.</param> 19 /// <returns></returns> 20 public static void UseConsul(this IApplicationBuilder app, IConfiguration configuration, IConsulClient consulClient) 21 { 22 RegisterConsul(configuration,consulClient); 23 } 24 25 /// <summary> 26 /// This method realizes the core Consul Registration and health examination. 27 /// </summary> 28 /// <param name="configuration">Configure the access type of the system.</param> 29 /// <param name="consulClient">Consul The client type of the.</param> 30 private static void RegisterConsul(IConfiguration configuration, IConsulClient consulClient) 31 { 32 var consulGroupName = configuration["ConsulGroup"]; 33 var ip = configuration["IP"]; 34 var port = int.Parse(configuration["Port"]); 35 var serviceID = $"{consulGroupName}_{ip}_{port}"; 36 37 AgentServiceCheck checkService = new AgentServiceCheck() { 38 HTTP = $"http://{ip}:{port}/HeartCheck", 39 Interval=TimeSpan.FromSeconds(6), 40 Timeout=TimeSpan.FromSeconds(2), 41 DeregisterCriticalServiceAfter=TimeSpan.FromSeconds(2) 42 }; 43 44 AgentServiceRegistration agentServiceRegistration = new AgentServiceRegistration() { 45 Name = consulGroupName, 46 Address = ip, 47 Port = port, 48 ID = serviceID, 49 Check= checkService 50 }; 51 52 consulClient.Agent.ServiceRegister(agentServiceRegistration); 53 } 54 } 55 }
D. in appsettings.json file, add consol configuration: "consolgroup": "userservice"
1 { 2 "Logging": { 3 "LogLevel": { 4 "Default": "Information", 5 "Microsoft": "Warning", 6 "Microsoft.Hosting.Lifetime": "Information" 7 } 8 }, 9 "AllowedHosts": "*", 10 "ConsulGroup": "UserService" //Configuration point 11 }
E. configure Startup.cs.
1 using Consul; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.AspNetCore.Hosting; 4 using Microsoft.Extensions.Configuration; 5 using Microsoft.Extensions.DependencyInjection; 6 using Microsoft.Extensions.Hosting; 7 using Microsoft.OpenApi.Models; 8 using System; 9 using PatrickLiu.MicroService.WeiXin.UserService.Utilities; 10 11 namespace PatrickLiu.MicroService.WeiXin.UserService 12 { 13 /// <summary> 14 /// dotnet PatrickLiu.MicroService.WeiXin.UserService.dll --urls="http://*:9156" --ip="127.0.0.1" --port=9156 15 /// 16 /// dotnet PatrickLiu.MicroService.WeiXin.UserService.dll --urls="http://*:9157" --ip="127.0.0.1" --port=9157 17 /// </summary> 18 public class Startup 19 { 20 /// <summary> 21 /// The instance accessed by the configuration is injected through the constructor. 22 /// </summary> 23 /// <param name="configuration">Configure accessors.</param> 24 public Startup(IConfiguration configuration) 25 { 26 Configuration = configuration; 27 } 28 29 /// <summary> 30 /// Gets an instance of the configuration accessor. 31 /// </summary> 32 public IConfiguration Configuration { get; } 33 34 /// <summary> 35 /// The service instance of the injected container. 36 /// </summary> 37 /// <param name="services"></param> 38 public void ConfigureServices(IServiceCollection services) 39 { 40 services.AddSingleton<IConsulClient>(c=> new ConsulClient(config=> { 41 config.Datacenter = "dc1"; 42 config.Address =new Uri("http://localhost:8500"); 43 })); 44 services.AddControllers(); 45 services.AddSwaggerGen(c => 46 { 47 c.SwaggerDoc("user", new OpenApiInfo { Title = "UserService", Version = "v1" }); 48 }); 49 } 50 51 /// <summary> 52 /// to configure Http The requested processing pipeline. 53 /// </summary> 54 /// <param name="app">Application builder.</param> 55 /// <param name="env">WebHost environment</param> 56 /// <param name="consul">Consul Client for.</param> 57 public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IConsulClient consul) 58 { 59 if (env.IsDevelopment()) 60 { 61 app.UseDeveloperExceptionPage(); 62 } 63 64 app.UseSwagger(); 65 app.UseSwaggerUI(option=> { 66 option.SwaggerEndpoint("/swagger/user/swagger.json", "UserService v1"); 67 }); 68 69 app.UseRouting(); 70 71 app.UseAuthorization(); 72 app.UseConsul(Configuration,consul); 73 74 app.UseEndpoints(endpoints => 75 { 76 endpoints.MapControllers(); 77 }); 78 } 79 } 80 }
F. configure the check type of heartbeat service.
using Microsoft.AspNetCore.Mvc; namespace PatrickLiu.MicroService.WeiXin.UserService.Controllers { /// <summary> /// Controller for heartbeat check. /// </summary> [Route("[controller]")] [ApiController] public class HeartCheckController : ControllerBase { /// <summary> /// Heartbeat detection results. /// </summary> /// <returns></returns> [HttpGet] public IActionResult Get() { return Ok(); } } }
G. extension type: in order to distinguish whether rotation training is carried out or not, a port attribute is added.
using System; namespace PatrickLiu.MicroService.WeiXin.UserService { public class WeatherForecast { public DateTime Date { get; set; } public int TemperatureC { get; set; } public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); public string Summary { get; set; } public int Port { get; set; }//Added attributes } }
H. controller of data providing type.
1 using Microsoft.AspNetCore.Mvc; 2 using Microsoft.Extensions.Configuration; 3 using Microsoft.Extensions.Logging; 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 8 namespace PatrickLiu.MicroService.WeiXin.UserService.Controllers 9 { 10 /// <summary> 11 /// Get the weather controller. 12 /// </summary> 13 [ApiController] 14 [Route("/user/[controller]")] 15 public class WeatherForecastController : ControllerBase 16 { 17 #region Private field 18 19 private static readonly string[] Summaries = new[] 20 { 21 "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 22 }; 23 24 private readonly ILogger<WeatherForecastController> _logger; 25 26 #endregion 27 28 #region Constructor 29 30 /// <summary> 31 /// Initializes a new instance of type. 32 /// </summary> 33 /// <param name="logger">Initialize the log object.</param> 34 /// <param name="configuration">Initialize the configuration object.</param> 35 public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration) 36 { 37 _logger = logger; 38 Configuration = configuration; 39 } 40 41 #endregion 42 43 #region Instance properties 44 45 /// <summary> 46 /// Gets the configuration object. 47 /// </summary> 48 public IConfiguration Configuration { get; } 49 50 #endregion 51 52 #region Core method 53 54 /// <summary> 55 /// Get the weather. 56 /// </summary> 57 /// <returns></returns> 58 [HttpGet] 59 public IEnumerable<WeatherForecast> Get() 60 { 61 var rng = new Random(); 62 return Enumerable.Range(1, 5).Select(index => new WeatherForecast 63 { 64 Date = DateTime.Now.AddDays(index), 65 TemperatureC = rng.Next(-20, 55), 66 Summary = Summaries[rng.Next(Summaries.Length)], 67 Port = int.Parse(Configuration["Port"])//Added code. 68 }) 69 .ToArray(); 70 } 71 72 #endregion 73 } 74 }
(3) project description.
In the Startup.cs file, we configure Consul and Swagger. The specific code is very simple, so I won't say more.
The project starts two instances. The startup code is as follows:
dotnet PatrickLiu.MicroService.WeiXin.UserService.dll --urls="http://*:9157" --ip="127.0.0.1" --port=9157
dotnet PatrickLiu.MicroService.WeiXin.UserService.dll --urls="http://*:9156" --ip="127.0.0.1" --port=9156
Consul managed services. As shown in the figure:
2]. The second WEB API instance program.
In fact, the first WebAPI project and the second WebAPI project are the same, but there are some configuration differences, not essential differences.
(1) screenshot of the project
(2) project source code
Since the project uses Consul for service discovery management, at the beginning of the project creation, the Consul component must be installed through Nuget. At the same time, Swashbuckle.AspNetCore must be introduced, which supports the implementation of Swagger.
A. create a WebAPI project named Patrick liu.microservice.weixin.productservice.
B. the Consul and Swashbuckle.AspNetCore component packages are introduced through Nuget respectively.
C. extend the Consul service and create one under the root directory Utilities file and create a class: ConsulManager.cs under this folder.
1 using Consul; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.Extensions.Configuration; 4 using System; 5 6 namespace PatrickLiu.MicroService.WeiXin.ProductService.Utilities 7 { 8 /// <summary> 9 /// Consul The extension type of Http Register in pipeline Consul. 10 /// </summary> 11 public static class ConsulManager 12 { 13 /// <summary> 14 /// register Consul Service instance. 15 /// </summary> 16 /// <param name="app">Application builder.</param> 17 /// <param name="configuration">Configure accessors for the system.</param> 18 /// <param name="consulClient">Consul The client type of the.</param> 19 /// <returns></returns> 20 public static void UseConsul(this IApplicationBuilder app, IConfiguration configuration, IConsulClient consulClient) 21 { 22 RegisterConsul(configuration,consulClient); 23 } 24 25 /// <summary> 26 /// realization Consul Real registration. 27 /// </summary> 28 /// <param name="configuration">Configure accessors for the system.</param> 29 /// <param name="consulClient">Consul The client type of the.</param> 30 private static void RegisterConsul(IConfiguration configuration, IConsulClient consulClient) 31 { 32 var consulGroupName = configuration["ConsulGroup"]; 33 var ip = configuration["IP"]; 34 var port = int.Parse(configuration["Port"]); 35 var serviceID = $"{consulGroupName}_{ip}_{port}"; 36 37 AgentServiceCheck checkService = new AgentServiceCheck() { 38 HTTP = $"http://{ip}:{port}/HeartCheck", 39 Interval=TimeSpan.FromSeconds(6), 40 Timeout=TimeSpan.FromSeconds(2), 41 DeregisterCriticalServiceAfter=TimeSpan.FromSeconds(2) 42 }; 43 44 AgentServiceRegistration agentServiceRegistration = new AgentServiceRegistration() { 45 Name = consulGroupName, 46 Address = ip, 47 Port = port, 48 ID = serviceID, 49 Check= checkService 50 }; 51 52 consulClient.Agent.ServiceRegister(agentServiceRegistration); 53 } 54 } 55 }
D. in the appsettings.json file, add the Consul configuration: "ConsulGroup": "ProductService".
1 { 2 "Logging": { 3 "LogLevel": { 4 "Default": "Information", 5 "Microsoft": "Warning", 6 "Microsoft.Hosting.Lifetime": "Information" 7 } 8 }, 9 "AllowedHosts": "*", 10 "ConsulGroup": "ProductService"//Registration service name 11 }
E. configure Startup.cs.
1 using Consul; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.AspNetCore.Hosting; 4 using Microsoft.AspNetCore.Mvc; 5 using Microsoft.Extensions.Configuration; 6 using Microsoft.Extensions.DependencyInjection; 7 using Microsoft.Extensions.Hosting; 8 using Microsoft.Extensions.Logging; 9 using PatrickLiu.MicroService.WeiXin.ProductService.Utilities; 10 using System; 11 using System.Collections.Generic; 12 using System.Linq; 13 using System.Threading.Tasks; 14 15 namespace PatrickLiu.MicroService.WeiXin.ProductService 16 { 17 /// <summary> 18 /// dotnet PatrickLiu.MicroService.WeiXin.ProductService.dll --urls="http://*:9158" --ip="127.0.0.1" --port=9158 19 /// 20 /// dotnet PatrickLiu.MicroService.WeiXin.ProductService.dll --urls="http://*:9159" --ip="127.0.0.1" --port=9159 21 /// </summary> 22 public class Startup 23 { 24 /// <summary> 25 /// 26 /// </summary> 27 /// <param name="configuration"></param> 28 public Startup(IConfiguration configuration) 29 { 30 Configuration = configuration; 31 } 32 33 /// <summary> 34 /// 35 /// </summary> 36 public IConfiguration Configuration { get; } 37 38 /// <summary> 39 /// 40 /// </summary> 41 /// <param name="services"></param> 42 public void ConfigureServices(IServiceCollection services) 43 { 44 services.AddSingleton<IConsulClient>(new ConsulClient(c=> { 45 c.Datacenter = "dc1"; 46 c.Address = new Uri("http://localhost:8500"); 47 })); 48 49 services.AddSwaggerGen(a => 50 { 51 a.SwaggerDoc("product", new Microsoft.OpenApi.Models.OpenApiInfo() { Title = "ProductService", Version = "v1" }); 52 }); 53 services.AddControllers(); 54 } 55 56 /// <summary> 57 /// 58 /// </summary> 59 /// <param name="app"></param> 60 /// <param name="env"></param> 61 /// <param name="consul"></param> 62 public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IConsulClient consul) 63 { 64 if (env.IsDevelopment()) 65 { 66 app.UseDeveloperExceptionPage(); 67 } 68 69 app.UseRouting(); 70 71 app.UseConsul(Configuration,consul); 72 73 app.UseSwagger(); 74 app.UseSwaggerUI(options=> { 75 options.SwaggerEndpoint("/swagger/product/swagger.json", "ProductService-V1"); 76 }); 77 app.UseAuthorization(); 78 79 app.UseEndpoints(endpoints => 80 { 81 endpoints.MapControllers(); 82 }); 83 } 84 } 85 }
F. configure the check type of heartbeat service.
using Microsoft.AspNetCore.Mvc; namespace PatrickLiu.MicroService.WeiXin.ProductService.Controllers { /// <summary> /// Heartbeat check controller. /// </summary> [Route("[controller]")] [ApiController] public class HeartCheckController : ControllerBase { /// <summary> /// Heartbeat detection method. /// </summary> /// <returns></returns> [HttpGet] public IActionResult Get() { return Ok(); } } }
(3) project description.
In the Startup.cs file, we configure Consul and Swagger. The specific code is very simple, so I won't say more.
The project starts two instances. The startup code is as follows:
dotnet PatrickLiu.MicroService.WeiXin.ProductService.dll --urls="http://*:9158" --ip="127.0.0.1" --port=9158
dotnet PatrickLiu.MicroService.WeiXin.ProductService.dll --urls="http://*:9159" --ip="127.0.0.1" --port=9159
Consul managed products and services. The screenshot is as follows:
3]. Our Ocelot gateway instance program.
This project is our key, sir. First of all, we will introduce Ocelot, ocelot.provider.consume and Swashbuckle.AspNetCore into the project, and start our configuration after the introduction.
(1) screenshot of the project
(2) project source code
A. create a WebAPI project with the name of Patrick liu.microservice.weixin.gateway.
B. configure Ocelot, ocelot.consume and Swagger in the Startup file.
1 using Microsoft.AspNetCore.Builder; 2 using Microsoft.AspNetCore.Hosting; 3 using Microsoft.Extensions.Configuration; 4 using Microsoft.Extensions.DependencyInjection; 5 using Microsoft.Extensions.Hosting; 6 using Microsoft.OpenApi.Models; 7 using Ocelot.DependencyInjection; 8 using Ocelot.Middleware; 9 using Ocelot.Provider.Consul; 10 11 namespace PatrickLiu.MicroService.WeiXin.Gateway 12 { 13 /// <summary> 14 /// dotnet PatrickLiu.MicroService.WeiXin.Gateway.dll --urls="http://*:5000" --ip="127.0.0.1" --port=5000 15 /// </summary> 16 public class Startup 17 { 18 /// <summary> 19 /// Configure the system through constructor injection. 20 /// </summary> 21 /// <param name="configuration">Configure the system.</param> 22 public Startup(IConfiguration configuration) 23 { 24 Configuration = configuration; 25 } 26 27 /// <summary> 28 /// Get the configuration system. 29 /// </summary> 30 public IConfiguration Configuration { get; } 31 32 /// <summary> 33 /// Registration service. 34 /// </summary> 35 /// <param name="services"></param> 36 public void ConfigureServices(IServiceCollection services) 37 { 38 services.AddSwaggerGen(c=> { 39 c.SwaggerDoc("v1",new OpenApiInfo() { Title="Gateway API", Version="v1" }); 40 }); 41 services.AddOcelot().AddConsul(); 42 services.AddControllers(); 43 } 44 45 /// <summary> 46 /// to configure Http Request processing pipeline and middleware. 47 /// </summary> 48 /// <param name="app">The generator for the application.</param> 49 /// <param name="env">Web Host environment.</param> 50 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 51 { 52 if (env.IsDevelopment()) 53 { 54 app.UseDeveloperExceptionPage(); 55 } 56 57 app.UseRouting(); 58 app.UseAuthorization(); 59 60 app.UseSwagger(); 61 //1,First, there is no need to /swagger start 62 app.UseSwaggerUI(o => { 63 o.SwaggerEndpoint("/user/swagger.json", "User-Service"); 64 o.SwaggerEndpoint("/product/swagger.json", "Product-Service"); 65 }); 66 67 app.UseEndpoints(endpoints => 68 { 69 endpoints.MapControllers(); 70 }); 71 72 app.UseOcelot(); 73 } 74 } 75 }
C. This is our top priority. Configure it in AppSettings.
1 { 2 "Logging": { 3 "LogLevel": { 4 "Default": "Information", 5 "Microsoft": "Warning", 6 "Microsoft.Hosting.Lifetime": "Information" 7 } 8 }, 9 "AllowedHosts": "*", 10 "Routes": [ 11 { 12 "DownstreamPathTemplate": "/swagger/product/swagger.json", //The downstream configuration should also be consistent with the configuration in their respective services. This is the second point 13 "DownstreamScheme": "http", 14 "UpstreamPathTemplate": "/product/swagger.json", //Upstream configuration is not required here/swagger At the beginning, it is consistent with the gateway configuration. This is the second point 15 "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], 16 "ServiceName": "ProductService", 17 "UseServiceDiscovery": true 18 }, 19 { 20 "DownstreamPathTemplate": "/swagger/user/swagger.json", //The downstream configuration should also be consistent with the configuration in their respective services. This is the second point 21 "DownstreamScheme": "http", 22 "UpstreamPathTemplate": "/user/swagger.json", //Upstream configuration is not required here/swagger At the beginning, it is consistent with the gateway configuration. This is the second point 23 "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], 24 "ServiceName": "UserService", 25 "UseServiceDiscovery": true 26 }, 27 //swagger Upper configuration 28 { 29 "DownstreamPathTemplate": "/user/{url}", //Both downstream and upstream configurations add the same identifier to access their own service files. This is the third point. 30 "DownstreamScheme": "http", 31 "UpstreamPathTemplate": "/user/{url}", //Both downstream and upstream configurations add the same identifier to access their own service files. This is the third point. 32 "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], 33 "ServiceName": "UserService", 34 "LoadBalanceOptions": { 35 "Type": "RoundRobin" 36 }, 37 "UseServiceDiscovery": true 38 }, 39 { 40 "DownstreamPathTemplate": "/product/{url}", //Both downstream and upstream configurations add the same identifier to access their own service files. This is the third point. 41 "DownstreamScheme": "http", 42 "UpstreamPathTemplate": "/product/{url}", //Both downstream and upstream configurations add the same identifier to access their own service files. This is the third point. 43 "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], 44 "ServiceName": "ProductService", 45 "LoadBalanceOptions": { 46 "Type": "RoundRobin" 47 }, 48 "UseServiceDiscovery": true 49 } 50 ], 51 "GlobalConfiguration": { 52 "BaseUrl": "http://localhost:5000", 53 "ServiceDiscoveryProvider": { 54 "Host": "localhost", 55 "Port": 8500, 56 "Type": "Consul" 57 } 58 } 59 }
(3) project description.
In the Startup.cs file, we configure Consul and Swagger. The specific code is very simple, so I won't say more.
The project starts an instance. The startup code is as follows:
dotnet PatrickLiu.MicroService.WeiXin.Gateway.dll --urls="http://*:5000" --ip="127.0.0.1" --port=5000
3. The effect is shown in the figure
4. Description of key points.
1]. Configure the ConfigServices and configure in the Startup.cs file of the gateway project. Configuration in configure does not need to start with / swagger. Remember.
1 /// <summary> 2 /// Registration service. 3 /// </summary> 4 /// <param name="services"></param> 5 public void ConfigureServices(IServiceCollection services) 6 { 7 services.AddSwaggerGen(c=> { 8 c.SwaggerDoc("v1",new OpenApiInfo() { Title="Gateway API", Version="v1" }); 9 }); 10 services.AddOcelot().AddConsul(); 11 services.AddControllers(); 12 }
1 /// <summary> 2 /// to configure Http Request processing pipeline and middleware. 3 /// </summary> 4 /// <param name="app">The generator for the application.</param> 5 /// <param name="env">Web Host environment.</param> 6 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 7 { 8 if (env.IsDevelopment()) 9 { 10 app.UseDeveloperExceptionPage(); 11 } 12 13 app.UseRouting(); 14 app.UseAuthorization(); 15 16 app.UseSwagger(); 17 //1,First, there is no need to /swagger start 18 app.UseSwaggerUI(o => { 19 o.SwaggerEndpoint("/user/swagger.json", "User-Service"); 20 o.SwaggerEndpoint("/product/swagger.json", "Product-Service"); 21 }); 22 23 app.UseEndpoints(endpoints => 24 { 25 endpoints.MapControllers(); 26 }); 27 28 app.UseOcelot(); 29 }
If this gateway is simply a gateway, you can comment or delete all other codes, but keep them Services. Addocelot(). Addconsult() and app.UseOcelot(), no problem. However, if you want to configure Swagger here, you can't comment other code.
2]. Swagger upstream configuration does not need to start with / swagger here, which is consistent with the gateway configuration. The downstream configuration should also be consistent with the configuration in their respective services. This is the second point.
3]. Ocelot routing configuration: / only when the same identifier is added to the downstream and upstream configurations can the files of their own services be accessed.
A. the service configuration of users in the gateway should be consistent with the routing configuration on the Controller in the API.
B. the service configuration of the products in the gateway should be consistent with the routing configuration on the Controller in the API.
3, Summary
Well, that's all for today. When Swagger is configured in the gateway, we don't have to jump around to view the interface documents, which is convenient for our use and maintenance. This function is very practical. There were many pits when it was configured, and I have almost filled them out now. As the saying goes, stupid birds fly first. It's a good thing to record this thing for your future reference. Maybe it can help other people in need. Don't forget the original heart, we continue to work hard. We make a little progress every day. God will live up to those who work hard.