专栏名称: 架构师之路
架构师之路,坚持撰写接地气的架构文章
目录
相关文章推荐
架构师之路  ·  世界上最SB的事情就是... ·  5 天前  
架构师之路  ·  认知层次不同的人,是很难沟通的 ·  1 周前  
高可用架构  ·  携程度假商品千亿日志系统架构演进 ·  1 周前  
51好读  ›  专栏  ›  架构师之路

REST之父,居然为了晋升答辩,搞了一个HATEOAS架构?(只聊技术)

架构师之路  · 公众号  · 架构  · 2024-09-03 08:10

正文

今天听到两个同学找我,说想试试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请求头中的AcceptContent-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使得:

前端简化的部分,后端更加复杂;

前端解耦的部分,后端更加耦合;

前端方便的部分,后端更加不方便了;

总之,架构整体效率下降了。


近期文章:
github宝藏,给人学的23个设计模式(收藏)
开发者学MySQL,这一个项目就够了(收藏)

朋友,你觉得HATEOAS怎么样?