Clean Architecture 中哪一层处理响应代码决策
Which layer to handle response code decision in Clean Architecture
目前正在使用 MediatR 和
实现 Clean Architure
IRequestHandler<IRequest<ResponseMessage>, ResponseMessage>
IRequest<ResponseMessage>
实现现在在业务逻辑层、基础设施和控制器之间分离,它们依赖于依赖注入和解耦。
目前在 Asp.Net 核心中实现,此框架支持在控制器中生成响应代码,如下例所示。
[HttpGet]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<IActionResult> GetObject([FromQuery] int Id)
{
...
return Ok(some_result_to_show); // This generates code 200
}
我想知道 Clean Architecture 层中的什么地方应该将做出的业务规则决策转化为正确的响应代码,以及进行这种调整的最佳实践或设置方法是什么。
似乎快速实施仍将在控制器中进行,但想知道这个决定是否属于业务规则或应用程序业务规则,应该在不同的层处理,然后再转换为表示层的响应代码。
如果 Asp.Net 核心或 MediatR(或任何其他库)具有支持此类设计的内置框架或功能。
绝对是应用程序/表示层,它是 MVC 或您的控制器。我建议您抛出仅用于一个目的的特定异常。
例如,当您查询数据时,您将有一个请求处理程序来查找应该使用给定 ID(GUID 或其他)找到的数据。现在该标识符有效,但它 none 存在于您的数据库中。您不想在处理程序中访问 httpcontext (even though you could),因为您的业务逻辑会耦合到 asp.net。抛出一个异常告诉你,找不到资源来产生 404 错误响应(我们称之为 ResourceNotFoundException 即)。对于该异常,您可以在控制器端点上方使用异常过滤器而不是数据注释。你可以有很多异常过滤器。每个都有自己的目的。
如果您这样做,您的业务逻辑将与任何应用程序/表示层分离,并且可以轻松地在您需要的任何地方重复使用。
如果您想查看异常过滤器如何工作的示例,我刚才已经为此创建了一个简单的解决方案。你可以找到它 here.
与您的问题没有直接关系,但不是 return 一个 IActionResult,当您想向客户端发送数据时,您也可以 return 一个数据传输对象。它还会产生一个 Http.OK 状态码。
我找到的一种方法如下
在业务层,
RequestMessageValidator : AbstractValidator<RequestMessage>
{
RuleFor(r => r).{ConditionSyntax}().WithErrorCode(ResponseCodeString);
}
然后在控制器中,
return StatusCode(
Convert.ToInt32(ValidationResult.Errors[0].ErrorCode),
ValidationResult.Errors[0].ErrorMessage);
目前正在使用 MediatR 和
实现 Clean Architure IRequestHandler<IRequest<ResponseMessage>, ResponseMessage>
IRequest<ResponseMessage>
实现现在在业务逻辑层、基础设施和控制器之间分离,它们依赖于依赖注入和解耦。
目前在 Asp.Net 核心中实现,此框架支持在控制器中生成响应代码,如下例所示。
[HttpGet]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<IActionResult> GetObject([FromQuery] int Id)
{
...
return Ok(some_result_to_show); // This generates code 200
}
我想知道 Clean Architecture 层中的什么地方应该将做出的业务规则决策转化为正确的响应代码,以及进行这种调整的最佳实践或设置方法是什么。 似乎快速实施仍将在控制器中进行,但想知道这个决定是否属于业务规则或应用程序业务规则,应该在不同的层处理,然后再转换为表示层的响应代码。 如果 Asp.Net 核心或 MediatR(或任何其他库)具有支持此类设计的内置框架或功能。
绝对是应用程序/表示层,它是 MVC 或您的控制器。我建议您抛出仅用于一个目的的特定异常。
例如,当您查询数据时,您将有一个请求处理程序来查找应该使用给定 ID(GUID 或其他)找到的数据。现在该标识符有效,但它 none 存在于您的数据库中。您不想在处理程序中访问 httpcontext (even though you could),因为您的业务逻辑会耦合到 asp.net。抛出一个异常告诉你,找不到资源来产生 404 错误响应(我们称之为 ResourceNotFoundException 即)。对于该异常,您可以在控制器端点上方使用异常过滤器而不是数据注释。你可以有很多异常过滤器。每个都有自己的目的。
如果您这样做,您的业务逻辑将与任何应用程序/表示层分离,并且可以轻松地在您需要的任何地方重复使用。
如果您想查看异常过滤器如何工作的示例,我刚才已经为此创建了一个简单的解决方案。你可以找到它 here.
与您的问题没有直接关系,但不是 return 一个 IActionResult,当您想向客户端发送数据时,您也可以 return 一个数据传输对象。它还会产生一个 Http.OK 状态码。
我找到的一种方法如下
在业务层,
RequestMessageValidator : AbstractValidator<RequestMessage>
{
RuleFor(r => r).{ConditionSyntax}().WithErrorCode(ResponseCodeString);
}
然后在控制器中,
return StatusCode(
Convert.ToInt32(ValidationResult.Errors[0].ErrorCode),
ValidationResult.Errors[0].ErrorMessage);