【问题标题】:HealthReport object structure produced by health checks endpoint freezes Swagger docs page健康检查端点生成的 HealthReport 对象结构冻结 Swagger 文档页面
【发布时间】:2021-05-28 21:57:42
【问题描述】:

我为我的 .Net 5 Web API 项目启用了健康检查

public sealed class Startup
{
    public void ConfigureServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddHealthChecks();

        // ...
    }

    public void Configure(IApplicationBuilder applicationBuilder, IWebHostEnvironment webHostEnvironment)
    {
        // ...

        applicationBuilder.UseHealthChecks("/health");

        // ...
    }
}

不幸的是,健康端点没有出现在 swagger 文档中。这就是为什么我创建了一个额外的控制器

[ApiController]
[Route("[controller]")]
public sealed class HealthController : ControllerBase
{
    private readonly HealthCheckService _healthCheckService;

    public HealthController(HealthCheckService healthCheckService)
    {
        _healthCheckService = healthCheckService;
    }

    [HttpGet]
    public async Task<ActionResult<HealthReport>> GetHealthIndication()
    {
        HealthReport healthReport = await _healthCheckService.CheckHealthAsync();

        if (healthReport.Status == HealthStatus.Healthy)
        {
            return Ok(healthReport);
        }

        int serviceUnavailableStatusCode = (int) HttpStatusCode.ServiceUnavailable;
        
        return StatusCode(serviceUnavailableStatusCode, healthReport);
    }
}

在运行应用程序时,Swagger 生成了很多模型。打开健康端点时,页面会冻结几秒钟,因为它必须加载 HealthReport 对象结构。

  • 我认为具有单个端点的 API 会因此而冻结是不好的……对此有什么建议吗?

  • 我什至必须创建自己的控制器,还没有任何集成吗?我正在寻找像.UseHealthChecks(HealthController.GetHealthIndication) 这样的解决方案

【问题讨论】:

    标签: c# .net-core asp.net-core-webapi .net-5


    【解决方案1】:

    TLDR;

    为 Swagger 配置中的 Exception 类添加架构映射。

    services.AddSwaggerGen(c =>
                {
                    c.MapType<Exception>(() => new OpenApiSchema { Type = "object" });
                });
    

    此代码会将带有异常类的 Schema 转换为对象,因此您在客户端面临的行为将最小化。


    说明:

    根本原因: Swagger 冻结,因为 swagger javascript 客户端正在尝试基于从 swagger json 获取的模式创建示例模型。

    如果您查看 Exception 类,它包含大量嵌套的属性和类型。如果我们指示 swagger 生成器将 Exception 类视为创建的 JSON 文件中的简单对象,客户端将不必花时间创建嵌套对象。 (或者您也可以在此转换中包含 TimeSpan 类)。

    有多种方法可以解决这个问题:

    1. 如上所述,只需指示 Swagger 生成器在配置级别本身映射类型。
    2. 如果您想基于特定的操作(Swagger 上下文中的操作)或控制器(Swagger 上下文中的文档)创建架构,那么您可以实现相应的过滤器并动态修改 Swagger 文档内容。 https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#override-schema-for-specific-types
    3. 创建您自己的响应模型:这是有道理的,因为随着时间的推移,HealthReport 的架构可能会发生变化,因此服务的输出可能会随着时间的推移而发生变化,而不会意识到这一点。

    我什至必须创建自己的控制器,还没有任何集成吗?我正在寻找解决方案。UseHealthChecks(HealthController.GetHealthIndication)

    Swashbuckle(Swagger 代码生成和 UI)使用反射和程序集文档(.xml 文件)来创建 swagger 文档,因此它不会扫描其他程序集以查找控制器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多