我们应该在同一解决方案中从MVC应用程序调用Web API吗?


33

我正在MVC中具有移动应用程序的项目中工作,因此很明显,我们必须使用Web API,以便可以在移动应用程序中使用它。

在开始开发网站时创建了API之后,我们感到困惑,并讨论了是使用API​​还是直接访问Business对象。最后,我们让更多有经验的开发人员来使用Web API,而不是直接使用Business对象。

我对此解决方案结构感到困惑。

1)为什么我们应该使用Web API并发出HTTP请求(这很耗时)来获取或放置数据,而不是直接使用相同解决方案中的业务对象。

2)在争论之后,他们说如果客户端要在不同的云服务器上托管API和Web并仅在API上应用扩展,或者他想为访问API和Web使用不同的url(这是合理的)。因此,在那种情况下,我们应该在同一解决方案中从MVC应用程序调用Web API吗?

3)如果我们将API和Web托管在不同的托管上,那么这意味着我们的Web将使用WebClient并在每个导航上都有HTTP调用。这样对吗?

4)如果我们要在不同服务器上同时使用API​​和Web托管的业务对象,则BL中的某些更改将需要更新这两个服务器上的构建。

5)或者我们应该只为API创建一个项目,并且可以添加视图或html页面来开发Web界面,这样我们就可以直接从ajax调用API。

据我所知,#5是最好的解决方案,或者API仅适用于第三方访问。如果我们在同一解决方案中具有DB,EF,数据层和业务层,则我们不应使用API​​进行HTTP调用并直接访问业务对象。(如果我错了,请纠正我)当移动应用程序或桌面或任何人想要访问应用程序时需要API,以便我们可以拥有相同的存储库和数据层。

在我的场景中,我必须创建API,因为我们也拥有移动应用程序,在项目API方面,我们称为业务层(单独的项目),业务层与数据访问层(单独的项目)进行通信。因此,我的问题是,如果我们将API和Web托管在不同的服务器上,那么调用API(这是一个HTTP请求)可能需要更长的时间,而不是在创建项目并且拥有.dll时使用业务层的方法。在API控制器中,我们只是将业务量转换为json格式。

我已经在互联网上进行搜索,但没有得到令人信服的答案。我发现了一个博客http://odetocode.com/blogs/scott/archive/2013/07/01/on-the-coexistence-of-asp-net-mvc-and-webapi.aspx,但又讨论了同一点在那个博客中,我的问题是为什么我们需要考虑场景#3?

更新:我们可以有不同的API项目和MVC项目,我们可以使用jvascript从Web调用API或使用MVVM模式。


MVVM或带有视图模型的MVC?
Andrew Hoffman 2014年

我们正在使用MVC
Ruchir Shah 2014年

好吧,那真的没有正确的答案。仅在提高API质量时调用API会有好处。(吃自己的狗粮)进行Inproc调用而不是通过服务进行调用还可以提高性能。
Andrew Hoffman 2014年

Google曾经经历过这个问题。他们的产品既是服务又是网站。我相信他们决定让自己的网站使用自己的服务。
Andrew Hoffman 2014年

2
是。developers.stackexchange.com/questions/148556/…stackoverflow.com/questions/3590561/…是很好的资源。有些会,有些不会。没有真正的“正确”方法。
Andrew Hoffman 2014年

Answers:


37

好问题!我一直在寻找一种更好的方式来组织我的项目。.您提出的每一个观点都有其优点,并探讨了各种解决方案结构,我不得不说,我同意这里的大多数意见:没有完美的解决方案。遇到此类问题时,您需要问自己几件事:该应用程序有多复杂?我需要集成多少个系统-或需要与该系统集成多少个系统?我打算进行多少测试?是否有独立的设计/ UI团队?我们需要扩展吗?什么是会话?

让我们看一下使用一些聪明的工程使事情真正爆炸的几种方案和方法(以及一些使事情更容易的技巧)。

在同一项目中同时托管API和网站
在这种情况下,您可能有一个包含零个或多个业务层项目和一个混合MVC / WebAPI项目(以及其他项目-实用程序等)的解决方案。

Pro的
一切都在一个地方。.无需费劲地处理复杂的消息传递(HttpClient调用),您可以拥有共享的会话状态(通过Cookie,InProc / OutOfProc会话的客户端和服务器),连接池,共享逻辑等部署再简单不过了。

Con的
Everything都在一个地方。这可能是最单一的结构。图层之间没有明确定义的接口。.最终导致高内聚性。懒惰的开发人员在处理这种类型的体系结构时会避免使用接口,这使测试非常痛苦。缩放/定位应用程序将很困难。

用途
我将这种项目结构用于一次性,内部或简单的应用程序。建立一个快速的系统来跟踪本地Y的篮球营注册情况?这是您的架构!

不同项目中的WebAPI和网站
我倾向于这种情况。您拥有一个(或多个)MVC项目和一个WebAPI项目的单一解决方案。

专业版的
模块化! 松耦合!每个项目可以独立运行,可以单独测试,也可以进行不同的管理。这使您可以根据需要更轻松地实施不同的缓存策略。通过在不同系统之间保持牢固的界限,您可以更轻松地建立合同,从而使您可以强制实施特定的使用模式并减少可能出现的摩擦(阅读:更少的错误,更少的滥用API的机会)。缩放要容易一些,因为您只需要缩放高负载的位即可。集成也变得更容易处理,因为从一开始就需要了解API的外观。

Con的
维护会有些困难。多个项目意味着您将需要项目/功能所有者来跟踪合并,合同(接口),部署等。代码维护,技术债务,错误跟踪,状态管理-都成为问题,因为它们可能需要基于不同的实现根据您的需要。这些类型的应用程序随着它们的增长也需要最多的规划和管理。

用途
构建一个现在可以拥有100个用户,下周/每月可以拥有100,000个用户的应用程序?该应用程序是否必须发送通知,管理复杂的工作流程并具有多个界面(Web +移动应用程序+ SharePoint)?周末有很多时间在忙于解决5000多个拼图吗?这是适合您的架构!

提示
上面已经概述了,我可以理解您的下一个项目可能看起来有些令人生畏。不用担心,这是我多年来学到的一些技巧。

  1. 尝试使用无状态会话。在较小的系统上,这可能意味着存储至少包含当前用户的内部ID和超时的加密cookie。较大的系统可能意味着存储具有简单会话ID的加密cookie,该cookie可能是从数据存储区(redis,表存储,DHT等)中获取的。如果您可以存储足够的信息,不必访问主数据库根据每个请求,您将处于一个不错的地方-但请尝试将Cookie保持在1k以下。
  2. 请注意,可能会有不止一种模型。尝试从模型和预测的角度进行思考(我在这里找到的链接不是很好。以为:一个人的库存项目是另一个人的订单行项目-相同的基本底层结构,但视图不同)。一些项目的每个逻辑/概念边界都有不同的模型(即,使用特定的模型与特定的API通信)。
  3. API无处不在!只要对象/类/结构暴露任何数据或行为,就在建立API。请注意其他实体或依赖项将如何使用此API。考虑一下如何测试此API。考虑与该API进行通信的内容(通过代码的其他对象?通过协议的其他系统?)以及如何公开该数据(强类型?JSON?*咳嗽?XML?)。
  4. 为自己拥有的东西而建,而不是从现在起两年后的想象。另一个答案引用了YAGNI-它们是绝对正确的!解决想象中的问题会使您的截止日期变得虚幻。为迭代设定可靠的目标并达到目标。部署!开发中的项目就是只有一个用户的项目-您!
  5. YMMV(您的里程可能会有所不同)。这里只有一个绝对值:存在一个问题,您正在构建解决方案。其他一切都完全悬而未决。上面的两个解决方案都可以取得巨大的成功-也是失败的。这完全取决于您,您的工具以及如何使用它们。轻轻踩一下,开发人员同伴!

2
好答案!希望我能为您的写作给予奖励,但是由于我想不起任何事情,所以我只会关注您的Twitter。:P

“强类型?JSON?*咳嗽* XML”我缺少什么?
亚历山大·德克

1
@AlexanderDerck我要提到三个不同的格式设置选项(尽管还有更多)。“笑话”是XML可能难以使用,并且通常会增加很多开销(序列化/反序列化)。这并不是说,有时没有必要(特别是与外部团体工作时)..
鲍比·d

6

直接直接访问您的业务对象(我想是您在控制器中的意思)将更快,更轻松。

如果客户端要在不同的云服务器上托管API和Web并仅在API上应用扩展该怎么办?或者他希望使用不同的URL来访问API和Web(有点逻辑)该怎么办?

然后,您需要分别托管它们...但这对我来说听起来并不合逻辑,您肯定希望同时扩展两者。您确定要满足此要求吗?听起来太过分了。请记住,YAGNI-如果您不需要它,请不要构建它。在需要时进行构建。

如果是我,我会使用最适合该站点的技术来构建站点,那么(如果)您需要其他人可以单独构建的服务。


我完全同意您的看法,因为事后扩展很重要,关注点分离对我来说确实很重要。考虑建立可以轻松升级或维护的技术变化,构建n层体系结构始终是一件好事。例如,用docker容器包装是将来要考虑的另一件事。
Ishwor Khanal '18

4

我会说; 更喜欢MVC通过HTTPClient调用WebAPI。绕过“核心dll”逻辑是压倒性的,但是主要优点是您的整个系统将可以通过HTTP对域对象进行单点访问...无论如何都行。客户端框架(AngularJS等)。...更好地将MVC视为另一个客户端...并且训练您的团队很好地管理API ...

保持简单。希望能有所帮助。谢谢..


不知道为什么这被否决了,但这是好的建筑的最佳答案
。imo

我在考虑这种情况,我认为从自己的MVC应用程序调用API是一个好主意-但我认为这与服务器逻辑中的此调用以及与之相关的其他问题有所不同。就我而言,我将实际上是从我的视图中调用它,在那里我将让Vue形成复杂的UI并将数据传递到该API。然后我意识到这是合法的,因为就我而言,它实际上是从视图与服务器端项目进行调用,并且在考虑任何类型的UI时无论如何都要进行任何http调用-如果是ASP制成的view则可能会更多。但是,仅在JS环境中有效。
瓦西里大厅

直接调用视图API是一个好主意....但是MVC视图是从服务器生成的,因此您还可以在呈现部分视图(Views)... RESS框架(RESS)之前从服务器处理数据,尤其是与服务器处理更相关的数据。 :响应式Web设计+服务器端组件)。...如果可以完全避免使用MVC,则最好使用PURE客户端框架(Angular / ReactJS)...
Manoj Kumar Bisht
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.