之前2020-5-6-restful理解 - huangtengxiao和大家介绍了对RESTful的理解。今天和大家介绍下RESTful中最重要的一个概念HATEOAS。


什么是HATEOAS

HATEOAS是Hypermedia as the Engine of Application State的缩写。

翻译过来就是超媒体即应用状态引擎

那这个是什么样的一个东西呢?

我们先来看一个现实中的问题。

问题来源

我们在项目开发中经常需要涉及同后端对接API。

对接的过程一般都是后端的同学给出一个文档,告诉我们有哪些API,可以获得什么样子的参数。

试想一下,如果有一天后端同学新增加了API,但是没有给这个API文档,那你该怎么办?

所以说API文档,成为了前后端对接的耦合因素。

HATEOAS解决什么问题

HATEOAS通过超媒体来提供客户端与服务器之间的交互。

即客户端可以通过一个简单的初始URI,并从返回值获取可以操作的其他信息。

这样一来,我们对接后端时,就几乎不需要额外的信息。

可以进一步实现前后端的解耦。

Richardson Maturity Model中,HATEOAS为于最高层,可以显著提升RESTful API的可发现性和响应的自解释性。

HATEOAS例子

说了这么多大家可能还不是很了解,这里我们举个例子。

假设我们有这么一个API,可以返回一个人和他孩子的名字。

GET /people/huangtengxiao

<person>
    <name>huangtengxiao</name>
    <children>
        <name>xiaohuang</name>
    </children>
</person>

那按照RESTfulAPI的方式,我们可以通过POST方法给他添加孩子

POST /people/huangtengxiao/children/xiaoxiaohuang
GET /people/huangtengxiao

<person>
    <name>huangtengxiao</name>
    <children>
        <name>xiaohuang</name>
        <name>xiaoxiaohuang</name>
    </children>
</person>

但是如果我们后台模式设置了约束,即每家只能生2个小朋友,那么这里继续调用post就会出问题。

POST /people/huangtengxiao/children/xiaoxiaohuang

<message>too many children</message>

但是这个约束是后台模型才能知道,客户端根本不知道是否有这样的约束。

此外如果之后服务端的约束变更为3个小朋友,那客户端除了尝试post也不能知道后端约束的变化。

使用HATEOAS

如果我们使用HATEOAS,这个例子会怎么样?

GET /people/huangtengxiao

<person>
    <name>huangtengxiao</name>
    <children>
        <name>xiaohuang</name>
    </children>
    <links>
    	<link rel="addChild" href="children/:name" type="POST"/>
    	<link rel="addPet" href="pets/:name" type="POST"/>
    </links>
</person>

看到区别了么,使用HATEOAS的RESTful API 不但返回了我们所需的数据,还额外返回了一个links数组。

很容易我们可以从里面看到客户端可以做的操作,例如在”children/:name”这个链接进行post,可以添加一个child。

而且我们还发现了可以在”pets/:name”这个链接进行post,可以添加一个pet。

这个是之前我们都没有发现的。

POST /people/huangtengxiao/children/xiaoxiaohuang
GET /people/huangtengxiao

<person>
    <name>huangtengxiao</name>
    <children>
        <name>xiaohuang</name>
        <name>xiaoxiaohuang</name>
    </children>
    <links>
    	<link rel="addPet" href="pets/:name" type="POST"/>
    </links>
</person>

当我们添加一个child之后,我们发现links中只剩下了addPet这一个功能了。

因为后端模型发现当前的children已经达到约束,因此,返回的响应中只给出了可执行的操作。

所以现在客户端可以更据返回的响应,决定自己的行为,真正实现了后端模型驱动。

HATEOAS实现

HATEOAS目前还只是一个guide,目前可以有各种类型的实现。

其中Hypertext Application Language - Wikipedia 是一种目前有较广影响的草案。

大家有兴趣也可以参考。


参考文档:


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/HATEOAS%E7%AE%80%E4%BB%8B.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系