ASP.NET MVC API vs Web API Async

本文关键字:API Web Async vs ASP MVC NET | 更新日期: 2023-09-27 18:29:20

我目前正在使用ASP.NETMVC和一个用于各种"API"的控制器。我使用的是从每个操作方法调用的服务/存储库模式。

类似于以下内容:

存储库:

    public IQueryable<Order> GetOrders()
    {
        return from sqlOrder in DB.Orders
               select new Order
               {
                   Id = sqlOrder.Id,
                   Name = sqlOrder.Name,
                   Price = sqlOrder.Price
               };
    }

服务:

    public List<Order> GetOrders()
    {
        return Repo.GetOrders().ToList();
    }

控制器/操作:

    public JsonResult GetOrders()
    {
        var orders = Service.GetOrders();
        return Json(orders, JsonRequestBehavior.AllowGet);
    }

一切都很好,但我正在考虑转向WEB API和Async/Await

类似于以下内容:

存储库:(无更改)

    public IQueryable<Order> GetOrders()
    {
        return from sqlOrder in DB.Orders
               select new Venue
               {
                   Id = sqlOrder.Id,
                   Name = sqlOrder.Name,
                   Price = sqlOrder.Price
               };
    }

服务:

    public async Task<List<Order>> GetOrders()
    {
        return await Repo.GetOrders().ToListAsync();
    }

控制器/操作:

    [ResponseType(typeof(List<Order>))]
    public async Task<IHttpActionResult> GetOrders()
    {
        var orders = await Service.GetOrders();
        return Ok(orders);
    }

首先,这种异步/等待和存储库模式有什么问题吗?

使用原始MVC框架作为端点的"API"有什么主要缺点吗?而不是使用"Web API"?

ASP.NET MVC API vs Web API Async

您几乎已经回答了自己的问题:)

通过使用async/await,iis工作线程可以重用线程。假设您的api每秒接收1000个调用。如果您的线程限制设置为100,那么900个调用将空闲等待,直到请求完全完成

然而,通过使用async/await,线程将更快地分配给900个等待的请求,负载将更快(更难)到达数据库

假设您有一个持续10秒的最大线程数为1.1 db的调用,并且服务器可以在50毫秒内从web请求启动db调用
通过使用async,您可以启动200 db调用(每50毫秒1次),而如果不释放该线程,则可以启动1次。

至于你的第二个问题:大多数人不会在他们的控制器内进行数据访问,但这会产生一个非常干净的&简单易懂的例子
如果我的项目足够简单(想想网格屏幕),我甚至更喜欢在控制器中使用EF语句,而不是创建DAL层
别忘了EF本身就是一个存储库,它甚至内置了一个工作单元。。。

编辑
将您的businessLogic封装在与控制器分离的层中确实是个好主意
你可以使用服务,并为你想做的每个查询公开一个方法,但我一直在走这条路,我通常发现我的服务会很快膨胀,因为开发人员会根据自己的意愿创建越来越多的方法

最近我采用了命令查询系统。查询只返回数据,命令只执行某些操作。分离有助于保持代码的简洁性,开发人员在创建一个全新的queryClass时会像只创建一个方法一样投入更多的精力(尽管影响是一样的)

我通常会让我的查询有点动态,但不会太多
例如,OrderQuery可以包含2个构造函数,1个带有customerID,1个带typeID),然后查询将根据其构造方式应用更多或更少的筛选器
如果我需要说所有销售价值超过X的最新订单,我可能会创建一个新的查询GetOrdersByValue
通过这种方式,查询本身可以保持干净和集中(这会提高速度,开发人员不会因为认识到他们的请求应该已经存在而重新激活轮子)。