单一责任原则webapi

时间:2015-06-28 20:17:01

标签: asp.net-web-api solid-principles single-responsibility-principle

我正在为一个应用程序构建一个WebAPI服务,我被困在十字路口,我理解SOLID原则,并希望按照这些原则实现我的WebAPI服务,但是我花了最近几天在实施中苦苦挣扎并希望得到社区的一些建议。

单一责任原则规定,每个班级都应对软件提供的单一功能负责(参见Solid Principles

我目前有两个ApiControllers,但会有更多,两个目前有Get,Post和Put功能,但每个控制器也需要一个搜索功能,我的问题是应该将搜索方法转移到一个单独的ApiController,例如SearchController。

例如:

我有一个用户控制器

public class UserController : ApiController {
    Get - returns a User
    Post and Put - Add and update a User
}

我有一个与上面相同的患者控制器,如果我在每个控制器中有我的搜索方法,我应该有一个SearchController,例如。

public class SearchController : ApiController {
    SearchUsers() - returns ICollection<User>
    SearchPatients() - returns ICollection<Patient>
}

我意识到没有明确的答案,只想对最佳实践提出一些建议

2 个答案:

答案 0 :(得分:2)

如果你对SRP感到疯狂并且没有找到适当的责任级别,那么你最终会无所事事。

我将用户控制器视为负责在用户资源API之间进行调解以及如何在应用程序内部实现该概念。在这种情况下,在单个控制器中进行所有api操作是有意义的。

那就是说我们遵循命令/查询分离,所以我们的控制器委托命令或查询来完成实际的工作。这样我们的控制器应该改变的唯一原因是我们想要改变我们提供的API。

答案 1 :(得分:1)

我会在相应的控制器上引入搜索作为操作,如果您想跟踪所有具有搜索操作的控制器,请在其上添加一个界面。

public interface ISearchable
{
    IHttpActionResult Search(string q);
}

public class UsersController : ApiController, ISearchable
{
    [Route("api/Users/Search")]
    [HttpGet]
    public IHttpActionResult Search([FromUri] string q)
    {
        var userRepo = new UserRepo();

        //this search method can be as complex as needed
        //search initials, middle names, phone numbers, whatever you need.
        var results = userRepo.Search(q);

        return this.Ok(results);
    }
}

用法:

https://domain.com/api/Users/Search?q=smith

这使您的客户非常清楚,因为他们不必了解特定的SearchController,它基本上就是一堆RPC。如果您考虑搜索是什么,它基本上是一个不是标准http动词的动词,所以我们将它作为动作附加到路线上。我们仍然在处理Users集合,类似于针对集合的GET或POST。由于我们没有将SEARCH作为有效的HTTP方法,因此动作是下一个最佳选择。

参考SOLID。这使您的控制器保持简单的控制器。它的工作(IMO)是控制请求并将其路由到逻辑。在这种情况下,它采用了路由,将其映射到UserRepo并执行了搜索方法。搜索不是控制器的工作,你有另一个班级做那个繁重的工作。控制器只是根据请求处理应该执行的逻辑。即使返回的数据也会通过序列化器推迟到管道中的后期,因此SOLID应该在控制器上保持为真。