健康检查端点生成的 HealthReport 对象结构冻结 Swagger 文档页面

Que*_*n3r 6 c# .net-core asp.net-core-webapi .net-5

我为我的 .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");

        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,健康端点没有出现在 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

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

在此处输入图片说明

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

小智 7

太长了;

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

services.AddSwaggerGen(c =>
            {
                c.MapType<Exception>(() => new OpenApiSchema { Type = "object" });
            });
Run Code Online (Sandbox Code Playgroud)

此代码会将具有 Exception 类的 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.GetHealthInspiration)

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