健康检查端点生成的 HealthReport 对象结构冻结 Swagger 文档页面
HealthReport object structure produced by health checks endpoint freezes Swagger docs page
我为我的 .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");
// ...
}
}
不幸的是,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)
的解决方案
TLDR;
在 Swagger 配置中为异常 class 添加架构映射。
services.AddSwaggerGen(c =>
{
c.MapType<Exception>(() => new OpenApiSchema { Type = "object" });
});
此代码会将带有异常 class 的架构转换为对象,因此您在客户端面临的行为将最小化。
解释:
根本原因:
Swagger 冻结,因为 swagger javascript 客户端正在尝试基于从 swagger json.
获取的模式创建示例模型
如果您查看异常 class,它包含大量嵌套的属性和类型。如果我们指示 swagger 生成器将异常 class 视为创建的 JSON 文件中的一个简单对象,客户端就不必花时间创建嵌套对象。 (或者您也可以在此转换中包含 TimeSpan class)。
有多种方法可以解决这个问题:
- 如上所述,简单地指示 Swagger 生成器在配置级别本身映射类型。
- 如果您想基于特定的 Action(Swagger 上下文中的 Operation)或 Controller(Swagger 上下文中的 Document)创建模式,那么您可以实现各自的过滤器并即时修改 Swagger 文档内容。 https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#override-schema-for-specific-types
- 创建您自己的响应模型:这是有道理的,因为随着时间的推移,HealthReport 的架构可能会发生变化,因此服务的输出可能会随着时间的推移而发生变化而没有意识到。
Do I even have to create my own controller, aren't there any integrations yet? I'm looking for a solution.UseHealthChecks(HealthController.GetHealthIndication)
Swashbuckle(Swagger codegen 和 UI)使用反射和程序集文档(.xml 文件)创建 swagger 文档,因此它不会扫描控制器的其他程序集。
我为我的 .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");
// ...
}
}
不幸的是,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)
的解决方案
TLDR;
在 Swagger 配置中为异常 class 添加架构映射。
services.AddSwaggerGen(c =>
{
c.MapType<Exception>(() => new OpenApiSchema { Type = "object" });
});
此代码会将带有异常 class 的架构转换为对象,因此您在客户端面临的行为将最小化。
解释:
根本原因: Swagger 冻结,因为 swagger javascript 客户端正在尝试基于从 swagger json.
获取的模式创建示例模型如果您查看异常 class,它包含大量嵌套的属性和类型。如果我们指示 swagger 生成器将异常 class 视为创建的 JSON 文件中的一个简单对象,客户端就不必花时间创建嵌套对象。 (或者您也可以在此转换中包含 TimeSpan class)。
有多种方法可以解决这个问题:
- 如上所述,简单地指示 Swagger 生成器在配置级别本身映射类型。
- 如果您想基于特定的 Action(Swagger 上下文中的 Operation)或 Controller(Swagger 上下文中的 Document)创建模式,那么您可以实现各自的过滤器并即时修改 Swagger 文档内容。 https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#override-schema-for-specific-types
- 创建您自己的响应模型:这是有道理的,因为随着时间的推移,HealthReport 的架构可能会发生变化,因此服务的输出可能会随着时间的推移而发生变化而没有意识到。
Do I even have to create my own controller, aren't there any integrations yet? I'm looking for a solution.UseHealthChecks(HealthController.GetHealthIndication)
Swashbuckle(Swagger codegen 和 UI)使用反射和程序集文档(.xml 文件)创建 swagger 文档,因此它不会扫描控制器的其他程序集。