问题
I am using Dotnet Core healthchecks as described here. In short, it looks like this:
First, you configure services like this:
services.AddHealthChecks()
.AddSqlServer("connectionString", name: "SQlServerHealthCheck")
... // Add multiple other checks
Then, you register an endpoint like this:
app.UseHealthChecks("/my/healthCheck/endpoint");
We are also using Swagger (aka Open API) and we see all the endpoints via Swagger UI, but not the health check endpoint.
Is there a way to add this to a controller method so that Swagger picks up the endpoint automatically, or maybe integrate it with swagger in another way?
The best solution I found so far is to add a custom hardcoded endpoint (like described here), but it is not nice to maintain.
回答1:
Still looking for a better solution, but a poor man's solution to this problem looks like this:
public const string HealthCheckEndpoint = "/my/healthCheck/endpoint";
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
var pathItem = new PathItem();
pathItem.Get = new Operation()
{
Tags = new[] { "ApiHealth" },
Produces = new[] { "application/json" }
};
var properties = new Dictionary<string, Schema>();
properties.Add("status", new Schema(){ Type = "string" });
properties.Add("errors", new Schema(){ Type = "array" });
var exampleObject = new { status = "Healthy", errors = new List<string>()};
pathItem.Get.Responses = new Dictionary<string, Response>();
pathItem.Get.Responses.Add("200", new Response() {
Description = "OK",
Schema = new Schema() {
Properties = properties,
Example = exampleObject }});
swaggerDoc.Paths.Add(HealthCheckEndpoint, pathItem);
}
回答2:
There is no built-in support, either you manually develop a poor man's solution like in the accepted answer or you develop an extension like mentionned in this GitHub issue: NetCore 2.2 - Health Check Support
Swashbuckle is built on top of
ApiExplorer
, the API metadata component, that ships with ASP.NET Core.If health-checks endpoints aren't surfaced by that, then they won't be surfaced by Swashbuckle. This is a fundamental aspect to the SB design and is unlikely to change anytime soon.
IMO, this sounds like a perfect candidate for a community add-on package (see https://github.com/domaindrivendev/Swashbuckle.AspNetCore#community-packages).
If there was a willing contributor, they could start a new project called
Swashbuckle.AspNetCore.HealthChecks
, that exposes an extension method onSwaggerGenOptions
for enabling the functionality - e.g.EnableHealthCheckDescriptions
. Then behind the scenes, this could be implemented as a Document Filter (see readme) that adds the relevant Operation descriptions to theSwagger/OAI
document generated by Swashbuckle.
回答3:
My workaround is to add the following dummy controller.
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Mvc;
using System;
[Route("[controller]")]
[ApiController]
[Produces("application/json")]
public class HealthController: ControllerBase
{
[HttpGet("")]
public UIHealthReport Health()
{
throw new NotImplementedException("");
}
}
回答4:
I used this approach and it worked well for me: https://www.codit.eu/blog/documenting-asp-net-core-health-checks-with-openapi
Add a new controller e.g. HealthController and inject the HealthCheckService into the constructor. The HealthCheckService is added as a dependency when you call AddHealthChecks in Startup.cs:
The HealthController should appear in Swagger when you rebuild:
[Route("api/v1/health")]
public class HealthController : Controller
{
private readonly HealthCheckService _healthCheckService;
public HealthController(HealthCheckService healthCheckService)
{
_healthCheckService = healthCheckService;
}
/// <summary>
/// Get Health
/// </summary>
/// <remarks>Provides an indication about the health of the API</remarks>
/// <response code="200">API is healthy</response>
/// <response code="503">API is unhealthy or in degraded state</response>
[HttpGet]
[ProducesResponseType(typeof(HealthReport), (int)HttpStatusCode.OK)]
[SwaggerOperation(OperationId = "Health_Get")]
public async Task<IActionResult> Get()
{
var report = await _healthCheckService.CheckHealthAsync();
return report.Status == HealthStatus.Healthy ? Ok(report) : StatusCode((int)HttpStatusCode.ServiceUnavailable, report);
}
}
One thing I noticed though is the endpoint is still "/health" (or whatever you set it to in Startup.cs) and not "/api/vxx/health" but it will still appear correctly in Swagger.
来源:https://stackoverflow.com/questions/54362223/integrating-healthcheck-endpoint-into-swagger-open-api-ui-on-dotnet-core