RESTful API 是指符合 REST 架构风格的 API 设计,而 REST 架构风格是对互联网规模架构(Internet Scale Architecture)的总结与提炼。这一切都源于 Roy Fielding 提出的一个问题:既然互联网(Internet)是人类迄今为止构造的最大的软件应用,那么到底是什么样的架构原则,支撑了如此规模的异构且互联的系统呢?我们能从中学习到什么,以帮助我们更好地构建软件?
在前端八股面试中,有一个经典题目叫“浏览器从输入 url 到显示网页的全过程”,大概流程可以总结成:
- DNS 解析出 IP 地址
- 建立 TCP 连接
- 客户端发出 HTTP 请求
- 服务端响应 HTTP 请求
- 浏览器解析 HTML CSS
- 渲染 DOM
- 执行 JS 代码,可能会 ajax 加载内容,再次渲染 DOM
- 加载媒体资源
- 浏览器缓存机制
我们会发现,我们整个过程中,我们不会关心 CSS、JS 文件来自哪里,也不会关心这些资源是否全部来自于同一个网站。从始至终,我们都是将这些关联的资源看作是一个完整的资源在消费。
如果我们从系统集成的角度看待这个过程。网站对其它资源的引用,实际上表示了对其他服务计算结果的整合。我们平时从外部引入的 sdk js 文件,比如百度分析。当页面引入到这个 js 资源时,实际上时完成对这个资源的整合并返回给浏览器。
无论是 css、js 这样的资源,还是通过抄链接引用的其他页面,都是服务端返回页面中描述的。而客户端则是需要根据服务端提供的描述,选择恰当的时机,访问这些关联的资源。这样的系统集成方式,我们称之为由服务器指导的客户端侧集成(Server-side guided client-side integration)
由于这些资源是由客户端发起的,并不是由客户端强制的,那么客户端完全可以按照自己的需求,有选择性的访问资源。
比如,在功能机时代,电脑端的偷菜网页小游戏,会在移动端显示成文字小游戏。也就是由于性能问题,不去选择加载各种图片和动画。
从这样的角度出发,我们可以将 CSS、JavaScript 或者网页中通过超链接引入的其它界面,都可以看作是当前页面的增强。比如 CSS 增强了当前页面的效果,js 增强了当前页面的交互,页面中的超链接为页面中的内容提供了额外的信息。于是通过超媒体格式,我们不仅可以描述当前的服务,还可以描述增强的服务。
这种按需索取增强服务,而不强制要求加载所有服务的形式,被称为渐进式的消费方式,促使互联网称为了一个异构、松耦合且开放的系统。
我们使用同样的 api,支撑起了完全不同的客户端。而且这些客户端,不知道彼此的存在,它们只关心自己的资源。
而这种后端只管提供接口,完全控制客户端的行为,也被称作 HATEOAS(Hypermedia As The Engine Of Application State),即超媒体作为应用程序状态的控制引擎,是最高成熟度的 Restful API
超媒体的基本思想,是通过超媒体元素来丰富资源的表示,比如下面这种
<link href="theme.css" rel="stylesheet" type="text/css" />
在 html 中,link 是表达关联资源的主要手段,主要分为两个部分:
- 指向关联资源的链接(href);
- 与主资源是哪种关联关系(rel); 比如上面就表明,这里有一个 stylesheet 资源,可以通过 theme.css 获取。 而在 spring hateaos 中,选择的是 HAL(Hypertext Application Language 来表示资源,比如:
{
"_links" : {
"self" : {
"href" : "https://myhost/people/42",
}
},
"firstname" : "Dave",
"lastname" : "Matthews"
}