转:咱们是否应该把后端构建为API

原文来自于:http://www.infoq.com/cn/news/2015/07/api-or-nothtml

不久前,在StackExchange网站上,一位名为SLC的用户提起他正在设计一个ASP.NET网站,他对因而否要将后端设计为API有些举旗不定,但愿可以获得一些建议。一石激起千层浪,这个帖子很快获得了大量的关注与回复。如今让咱们来了解一下SLC所面临的具体状况与问题。数据库

SLC设计的网站是一个典型的ASP.NET MVC应用,他在开发时使用的都是一些经典的MVC模式,即控制器、视图与模型的结合,在控制器的方法中调用某个Manager对象以获取数据并建立视图模型。原本没什么问题,但他的某位同事对此表示异议,认为这种代码的耦合性太强,如若要建立一个桌面版本的应用,这些代码就没法重用了。他所推崇的最佳实践是建立一套API,在此基础上开发网站、桌面应用或者移动应用就都不成问题了。后端

SLC对此见解持保留意见,他列举了几条他认为这种作法不合适的缘由:api

  • 将后端设计为API有过分抽象之嫌,巨大的灵活性同时也意味着巨大的复杂度;
  • MVC中的一些内置特性将变得无用武之地,例如与角色和认证相关的功能都要从新设计;
  • 为了保证API调用的安全性,必须设计某种令牌系统,在每次API调用中都要附加相应的令牌;
  • 整个程序中的每一个功能都必须编写一个对应的API调用;
  • 在API中没法利用接口或抽象类等工具,像WCF这样的框架对于接口的支持很是有限;
  • 在桌面或移动应用中一般要避免细粒度的API调用,所以不得不为支持这些系统建立一些批量方法或粗粒度的方法;
  • 这违反了YAGNI原则,除非你已肯定要同时支持多种具有相同功能的应用,不然只是无谓地增长开发工做量;
  • 因为没法实现端到端的单步执行,调试变得很是困难。

支持者

用户gbjbaanb坚定支持使用API设计后端的方式,他认为这种方法不只使得代码能够重用,而且可以带来更高的安全性与更好的设计。而一体性的实现会形成架构的僵化,难以扩展、替换及改进。他还以时下最流行的微服务为例,在这种设计中的后端实现为多个小型的服务,它们各自提供一套API以供客户端进行调用。他同时也指出了SLC对于API的概念存在误解之处,API并不是一种远程类库,而更像是一种提供数据的服务。网站能够经过API获取数据,并在本地对数据进行某些操做。安全

gbjbaanb也对SLC所列举的部分观点进行了点评:服务器

  • MVC自己就是遵循隔离服务概念的一种设计,只是ASP.NET MVC框架将这些设计元素组织在一块儿而已。所以使用API并不表明放弃了MVC思想,只是缺乏了这一框架中的一些辅助方法。若是过于依赖这些辅助方法,就等于将本身绑定在这一框架上,这种状况下能够编写本身的辅助方法,或寻找一些第三方类库。
  • 调试也同样简单。首先因为API是一个独立的层,所以彻底能够对API进行隔离测试,这种状况下甚至不须要进行调试。若是确实须要进行端到端的调试,那么也能够打开多个Visual Studio,同时附加到多个进程上进行调试。
  • 为了保证安全性而进行额外的设计,这实际上是一件好事。若是将全部安全方面的代码都实如今网站中,一旦黑客攻破了Web服务器,就等于得到了全部访问权,包括数据库。而若是设置了一个额外的API层,那么安全性就能够大大提升。

gbjbaanb最后为SLC提了一些设计方面的建议,从分层架构的角度看,网站是一种展现层,而API则是应用层。对于业务逻辑的设计能够看状况选择以数据为中心,或是以领域为中心的方式,固然后者显得更“纯净”一些。架构

反对者

而反对API的声音也很多。fotijr表示虽然微服务是当下的热点,但这不表明这种作法老是值得的。松耦合当然是好事,但若是所以让整个开发周期变得过于痛苦,那就得不偿失了。他同时建议将模型放在一个独立的数据访问项目中,以便MVC或桌面应用能够直接重用。JacquesB也不支持设计为API的作法,他认为单纯地建立API并不可以保证松耦合性,若是设计不当,反而会出现跨服务器边界的紧耦合性。框架

一点拙见

接下来笔者将简单地表达一下对此问题的我的意见。首先是对API的理解,原做者彷佛将API简单地理解为一种独立进程的分布式的API,例如Web API、Remoting或RPC调用。其实从广义上来讲,只要是经过代码调用后台的业务逻辑与数据,均可以理解为一种API。所以问题不在于要不要设计API,而是如何设计这套API。分布式

接下来看一下原做者的设计方式,他所使用的方法是在控制器方法内调用某个Manager对象的方法以访问数据,那么大概能够推测出他的业务逻辑是以一种以数据为中心的设计思想,所使用的模式极可能是事务脚本(Transaction Script)。这种方式的优势在于简单易懂,但这样设计出的模型极可能是一种贫血模型,即业务逻辑大量散落在对应于用例的应用层的方法中,随着时间的推移,其难以维护的缺点将会逐渐暴露出来。微服务

比较好的方式是遵循关注分离的设计原则,将业务逻辑与对应用例的应用逻辑进行隔离,将业务逻辑放在一个具备高度内聚性的领域层中,而展现层(即网站、桌面或移动应用)经过应用层间接地调用相应的业务逻辑。从这一角度来讲,SLC所需的API正是应用层所暴露的方法与对象(例如数据传输对象),而他本人在以后的回复中也表示了对这一点的理解。至因而否要将应用层的API设计为分布式,这已经不是主要的问题所在了。

关于经过API实现重用性,让同一套逻辑可以适用于不一样的展现层,这一点笔者并不认同。诚然,在分层架构(或其它相似的架构)中,理论上是有可能重用相同的应用逻辑的。但在实际应用中,因为客户端的不一样特性,每每会对应用逻辑进行某种程度的调整,以实现最优化的用户体验。在网站中使用的Composite UI风格,在移动端可能会被设计为Task Based UI,而UX以及用例的区别将直接致使应用层API的变化。若是要坚持重用应用逻辑,势必要对UX做出某种程度的妥协,在作出重用这一决定时,软件组织必须对它的影响有深入的理解。

其实在笔者看来,分层的最大好处在于保持了设计与代码的整洁性,有利于长期的设计演变与代码维护,而且可以促进单元测试,同时能够对不一样的层进行并行开发、测试与部署。相信这也是SLC的同事的本意所在。

相关文章
相关标签/搜索