我正在设计一个将与另一个系统集成的api,但是我偶然发现了一个代码,我知道它可以改进,但我不知道如何正确地进行。
[HttpPost]
[Route("Reserve")]
public IHttpActionResult Reserve([FromUri]ReserveData reserveData, [FromBody]BetsData bet)
{
var result = new ReserveResponse();
// Question 1.
if (reserveData == null || !IsDataForReserveValid(reserveData))
{
// Question 2.
return Ok(_responseStringBuilder.BuildWrongRequestResponse().Create());
}
// Question 3.
if (!_customerService.CheckIfCustomerExists(reserveData.cust_id))
{
return Ok(_responseStringBuilder.BuildCustomerNotFoundResponse().Create());
}
if (_customerService.IsCustomerRestricted(reserveData.cust_id))
{
return Ok(_responseStringBuilder.BuildRestrictedCustomerResponse().Create());
}
if (!_reserveService.ReserveAmount(reserveData.cust_id, reserveData.amount))
{
return Ok(_responseStringBuilder.BuildInsufficientFundsResponse().Create());
}
if (bet != null)
{
}
_reserveService.InsertReserve(reserveData);
return Ok(_responseStringBuilder.BuildNoErrorsResponse().Create());
}
这是一个简单的操作,应该在其响应内容中返回带有字符串的Ok。
我已经在控制器中放了一些业务逻辑,但是我不确定它是否应该在服务层中。我应该这样离开它还是从服务中调用单个方法所有的逻辑本身就在那里,如果有错误,只需将结果返回给我?
Example response would be:
...(some data)
error_code=NoErrors\r\n
error_message=There were no errors\r\n
答案 0 :(得分:2)
这是我的2美分:
检查有效输入有什么好处吗?
如果可能,请将验证属性放在模型上以进行基本验证。请参阅this作为示例。
对于更多面向业务的验证,我认为它应该发生在封装操作的方法中,因此您对客户限制和其他内容的检查将会在那里进行。如果出现问题,该方法可能会抛出有意义的消息,然后您可以捕获异常,获取消息并使用它构建响应。
我已经创建了字符串构建器模式,每次我的请求都会构建所需的属性。这是最好的方式吗?
正如你所说,你需要一个字符串作为回应。有没有特定的格式?如果是,我建议利用custom formatters将格式化逻辑放在一个地方。
我应该这样离开它还是从一个服务中调用单个方法,该服务在那里完成所有逻辑,如果有错误,只返回结果给我?
典型的服务层应关注业务验证和业务逻辑。也就是说,请求和原语验证的格式可以放在此方法之外,但方法本身应该验证传递的参数,并且不能依赖于正确提供它们的调用者。但是,我应该注意到这些问题是非常固执的,取决于特定的用例。有很多可能的方法,没有理由让控制器成为代理,就像没有理由让控制器膨胀一样。
此外,这可能应该转到https://codereview.stackexchange.com/。