【问题标题】:single responsibility principle webapi单一职责原则 webapi
【发布时间】:2015-06-28 20:17:01
【问题描述】:

我正在为一个应用程序构建一个 WebAPI 服务,我被困在一个十字路口,我了解 SOLID 原则并希望按照这些原则实现我的 WebAPI 服务,但是我在过去几天一直在努力实现并希望得到社区的一些建议。

单一职责原则指出,每个类都应对软件提供的单一功能部分负责(参见Solid Principles

我目前有两个 ApiController,但还会有更多,这两个目前具有 Get、Post 和 Put 功能,但每个控制器还需要一个 Search 功能,我的问题是是否应该将搜索方法移入一个单独的 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>
}

我知道没有明确的答案,只是想就最佳实践提出一些建议

【问题讨论】:

  • “搜索”可能只是一个带有过滤器的 GET,对吧?

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


【解决方案1】:

如果您对 SRP 发疯并且没有找到适当的责任级别,那么您最终会导致无数班级无所事事。

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

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

【讨论】:

  • 不过,我假设每个命令/查询都被注入到 ApiController 中。这意味着每个动作可能至少使用一个,但可能不使用其他动作中的任何一个。这导致 webapi 控制器充满了依赖项,其中仅使用了一些依赖项。在这种情况下,我更喜欢每个方法使用一个类,并确保将它们放在一个清晰的文件夹结构中,以防止东西变得一团糟。
【解决方案2】:

我会将搜索作为相应控制器上的操作引入,如果您想跟踪所有具有搜索操作的控制器,请在其上放置一个接口。

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

这让您的客户非常清楚,因为他们不必知道基本上是一堆 RPC 的特定 SearchController。如果您考虑一下什么是搜索,它基本上是一个动词,不是标准的 http 动词,所以我们将它作为一个动作附加到路由上。我们仍在对用户集合采取类似于针对集合的 GET 或 POST 的操作。由于我们没有将 SEARCH 作为有效的 HTTP 方法,因此操作是次优的。

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

【讨论】:

  • 鉴于您显示的Usage Url实际上是使用查询字符串,参数属性实际上不应该是[QueryString]吗?
  • @ScottK.Fraley [FromUri] 按预期工作,我在许多 WebApi 项目中都使用过它。我从未尝试过 [QueryString],所以我必须试一试。感谢您向我指出要尝试的新事物。
  • 好吧,我会的。我一直认为[FromUri] 意味着它(任何给定的参数)必须是 URL 的一部分,例如api/bla/Param1Value 并且不适用于查询字符串。谢谢你教我一些我不知道的东西! (但当然应该尝试过!)
猜你喜欢
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 2013-03-16
  • 2011-11-16
相关资源
最近更新 更多