随着 RESTful API 被越来越多地人接受,它已经被非常广泛地使用,并且,在日常开发中,大部分开发者写的 API 也越来越符合 RESTful 的规范。RESTful 系统设计中有一个重要的特性,就是 用超媒体驱动应用状态(Hypermedia as the engine of application state),也就是 HATEOAS。
先来通俗地介绍一下 HATEOAS。
通常我们开发 RESTful API 为时提供接口服务时,会有一份前后端对接的文档,这个文档里包含了每一个接口的请求地址、参数、响应内容等信息,虽然我们会对这些接口根据业务模块进行分类或者分组,但其实,每一个接口都是独立的,他们之间没有关系。这是不采用 HATEOAS 的接口开发方式。
与之相比,HATEOAS 可以类比我们日常浏览网页。比如,我们日常浏览掘金网站的时候,并不需要分别记住首页、文章列表、沸点、个人主页等功能页面的地址,而是,进入首页(或者任何一个页面)后,可以通过超链接的方式,进入任何与当前页面相关的页面。包含 HATEOAS 特性的 RESTful API 与之类似,就是在相应结果中,包含了与当前内容相关的接口的地址。这样,我们只需要知道一个「根接口」的地址,就可以像浏览一个网站一样,得到所有 API 的请求地址。
据一个例子,以下是一个请求的响应 JSON:
{
"bookId": 1,
"bookName": "一本简单的书",
"author": "张三",
"links": [
{
"rel": "self",
"type": "get",
"href": "http://xxx.com/books/1"
},
{
"rel": "collection",
"type": "get",
"href": "http://xxx.com/books"
}
]
}
其中的 links
字段,就是相应结果中包含的相关接口的请求地址(href)、请求方法(type)、类型(collection),类型中,rel 值为 self 的一个,就是当前接口。
在相关的标准中,常用的 rel 的值还包括edit、search、related、first、last、previous、next等,从这些值的名称中,你就可以知道它们指代的意思。
这样做的好处正如前文中举的例子那样,只要知道了一个初始的 API 资源地址,就能动态地发现与之相关的资源和可用的操作,API 接口之间就像网页与网页之间一样,通过超链接的方式连接了起来。而客户端无需使用硬编码的方式来保存每个接口的地址,只需要业务流程中涉及的每一个步骤就可以了。
在服务端开发中,很多用来开发 REST 服务的框架,也提供了 HATEOAS 相关的特性,比如在 Spring Boot 中,可以使用 spring-boot-starter-hateoas 起步依赖。