Integrating HealthCheck endpoint into swagger (open API) UI on dotnet core

我们两清 提交于 2019-12-11 11:29:52

问题


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 on SwaggerGenOptions 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 the Swagger/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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!