今天听到两个同学找我,说想试试HATEOAS,方便通过晋升答辩,被我严词拒绝。任何针对晋升的技术选型,都是耍流氓。
殊不知,HATEOAS,正是行业大拿Roy Fielding在他的博士论文里搞出来的东西。
画外音:假装幽默。
Roy Fielding,何许人也?
计算机科学家,架构师,HTTP协议核心设计者,Apache Web Server核心作者,REST之父。
什么是REST?
REST(Representational State Transfer),(资源)表现层状态转移,由Roy Fielding提出,它是一种满足一定约束条件的前端架构风格。
资源表现层状态转移,这个架构风格中有一些核心要素:
(1)资源(Resource):可以理解为数据,用户数据,订单数据,支付数据等;
(2)表现层(Representational):资源的表现形式,JSON,XML等;
(3)状态转移(State Transfer):资源状态变化,增删查改;
我们常说的RESTful风格架构,其核心是面向资源的架构(Resource-Oriented Architecture),通过HTTP协议的具体化实践,可以这么理解:
(1)资源通过URI来标识,通过URI的访问来实现资源的互动;
(2)对资源的增删查改状态转移,通过HTTP的POST/DELETE/GET/PUT方法来指定;
(3)资源的表现形式,通过HTTP请求头中的Accept和Content-Type来指定;
举例,这是一个RESTful风格的接口:
GET abc.com/account/shenjian { "result": "OK", "data": { "name": "shenjian", "uid": "1234", "money": "100" } }
反例,这不是一个RESTful风格的接口:
POST abc.com/update/account/1234 { "money": "80" }
画外音:修改操作,却用了POST方法。
可以看到,RESTful的URI中,一般没有get/del/update等这些动词,资源的状态转移,是通过HTTP的方法来描述的。
画外音:当然,很多人在设计URI的过程中,也没有认真考虑这些规范,觉得这是强迫症。
什么是HATEOAS?
HATEOAS(Hypertext As The Engine Of Application State),也是Roy Fielding提出的,是一种更高成熟度的RESTful架构风格,超文本作为应用状态的引擎。
画外音:好拗口。
其特点是:
(1)一个资源访问的返回结果中,包含该资源相关联的操作信息;
(2)无需在前端中硬编码资源的相关操作,降低前端复杂性,使得前端代码更具备扩展性,更容易维护,减少对API文档的依赖;
画外音:好抽象。
举个具体的例子,大家就明白了。前文中的例子,获取用户余额接口,返回了用户的余额100元。
GET abc.com/account/shenjian { "result": "OK", "data": { "name": "shenjian", "uid": "1234", "money": "100" } }
站在业务的角度想想看,用户获取了余额,后续可能会干嘛呢?存钱、取钱、转账...
HATEOAS要求通过links直接返回潜在的URI关联操作:
GET abc.com/account/shenjian { "result": "OK", "data": { "name": "shenjian", "uid": "1234", "money": "100" }, "links": [ { "rel": "deposit", "href": "abc.com/account/1234/deposit" }, { "rel": "withdraw", "href": "abc.com/account/1234/withdraw" }, { "rel": "transfer", "href": "abc.com/account/1234/transfer" } ] }
但获取用户余额接口,如果用户的余额是-100元,此时用户只能继续存钱,无法取钱和转账,那么返回的内容就会有所不同:
GET abc.com/account/shenjian { "result": "OK", "data": { "name": "shenjian", "uid": "1234", "money": "-100" }, "links": [ { "rel": "deposit", "href": "abc.com/account/1234/deposit" } ] }
在返回资源数据的同时,还带上了该资源在这种状态下的潜在操作,降低前端架构的复杂性,提高前端架构的扩展性。
为什么说HATEOAS是个大坑?
HATEOAS是一种站在前端的角度,理想化的前端引擎:
(1)它极大的增加了后端的复杂性,同一个接口,后端需要理解返回的数据的业务含义,来决定增加哪些资源操作的URI;
(2)原本单纯的后端资源访问接口,变得与业务逻辑耦合。
画外音:我返回余额就好了,为什么要理解-100,0,100,1000的业务数据含义?
而且,这种理想化的“完备性”,与目前流行各种轻量级前端框架理念(React,Angular等)相违背,与快速开发快速迭代的简化API设计理念相违背,几乎没有工具与框架支持。
HATEOAS使得:
前端简化的部分,后端更加复杂;
前端解耦的部分,后端更加耦合;
前端方便的部分,后端更加不方便了;
…
总之,架构整体效率下降了。