Возможно ли динамически добавлять SwaggerEndpoints для SwaggerUI?
Мы создаем сервис-ориентированную архитектуру в.NET Core. Мы решили использовать Ocelot в качестве нашего шлюза API. Я интегрировал Ocelot с Консулом для обнаружения услуг. Сейчас я пытаюсь создать унифицированный интерфейс Swagger для всех последующих сервисов.
До обнаружения службы у нас была настроена Swagger, как это:
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger(c => { c.RouteTemplate = "{documentName}/swagger.json"; });
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/docs/customer/swagger.json", "Customers Api Doc");
c.SwaggerEndpoint("/docs/employee/swagger.json", "Employee Api Doc");
c.SwaggerEndpoint("/docs/report/swagger.json", "Reports Api Doc");
});
В интерфейсе Swagger это обеспечивает выпадающий список "выберите спецификацию". Разработчикам нравится эта функциональность, и мы хотели бы сохранить ее. Однако теперь, когда мы удалили ручную конфигурацию в пользу обнаружения службы, мы также хотели бы динамически обновлять эти конечные точки.
Имеется ли в наличии текущее решение Swagger, возможно ли это? Я не видел ничего, связанного с обнаружением служб или возможностью динамически настраивать пользовательский интерфейс. Мысли и предложения?
Обновить
Я придумал способ сделать это. Это немного хакерство, и я надеюсь, что есть способ сделать это, который не так жесток.
public class Startup
{
static object LOCK = new object();
SwaggerUIOptions options;
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<SwaggerUIOptions>((provider) =>
{
return this.options;
});
services.AddSingleton<IHostedService, SwaggerUIDocsAggregator>();
services.AddSingleton<IConsulDiscoveryService, MyCounsulDiscoveryServiceImplementation>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger(c => { c.RouteTemplate = "{documentName}/swagger.json"; });
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUI(c =>
{
this.options = c;
});
}
}
public class SwaggerUIDocsAggregator : IHostedService
{
static object LOCK = new object();
IConsulDiscoveryService discoveryService;
SwaggerUIOptions options;
Timer timer;
bool polling = false;
int pollingInterval = 600;
public ConsulHostedService(IConsulDiscoveryService discoveryService, SwaggerUIOptions options)
{
this.discoveryService = discoveryService;
this.options = options;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
this.timer = new Timer(async x =>
{
if (this.polling)
{
return;
}
lock (LOCK)
{
this.polling = true;
}
await this.UpdateDocs();
lock (LOCK)
{
this.polling = false;
}
}, null, 0, pollingInterval);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
this.timer.Dispose();
this.timer = null;
}
private async Task UpdateDocs()
{
var discoveredServices = await this.discoveryService.LookupServices();
var urls = new JArray();
foreach (var kvp in discoveredServices)
{
var serviceName = kvp.Key;
if (!urls.Any(u => (u as JObject).GetValue("url").Value<string>().Equals($"/{serviceName}/docs/swagger.json")))
{
urls.Add(JObject.FromObject(new { url = $"/{serviceName}/docs/swagger.json", name = serviceName }));
}
}
this.options.ConfigObject["urls"] = urls;
}
}
0 ответов
Простой способ интеграции шлюза API Ocelot в качестве единого пользовательского интерфейса Swagger для всех последующих сервисов - это проект https://github.com/Burgyn/MMLib.SwaggerForOcelot.