REST 软件架构

Web 技术发展

World Wide Web(万维网),简称 Web,是一种基于超文本和 HTTP 的、全球性的、动态交互的、跨平台的分布式图形信息系统。

web 形式发展

先后经历了 web 1.0 —> web 2.0 —> web 3.0

web 1.0
开始于 1994 年,主要是静态的 HTML 页面发布信息,其特点是:信息杂乱无序,只满足了人们对信息的搜索、传递需求。

web 2.0
开始于 2004 年,在 web 2.0 中,软件被当成一种服务,Internet 从一系列网站演化成一个成熟的为最终用户提供网络应用的服务平台,强调用户的参与、在线的网络协作、数据储存的网络化、社会关系网络、RSS 应用以及文件的共享等成为了 web 2.0 发展的主要支撑和表现。web 2.0 模式大大激发了创造和创新的积极性,使 Internet 重新变得生机勃勃。web 2.0 的典型应用包括 Blog、Wiki、RSS、Tag、SNS、P2P、IM 等。其特点是:更加注重交互性;核心是指导思想;与 1.0 没有绝对的界限。

web 3.0
正在步入 3.0,其特点是:智能化及个性化搜索引擎;数据的自由整合与有效聚合;适合多种终端平台,实现信息服务的普适性。

web 开发技术几个阶段

  1. 静态内容阶段
    这个阶段 web 服务器作为共享文件服务器,存的大多是静态的 HTML 文档。

  2. CGI 程序阶段
    这个阶段 web 服务器增加了一些编程 API,通过 API 可以向客户端提供一些动态变化的内容。通信使用 CGI(Common Gateway Interface)协议。

  3. 脚本语言阶段
    这个阶段服务端出现 ASP、PHP、JSP 等,浏览器端出现 Java Applet、Js 等,提供了更加丰富的内容。

  4. 瘦客户端应用阶段
    这个阶段出现了 MVC 模式,服务器端生成全部的动态内容。

  5. RIA 应用阶段
    这个阶段出现了大量的 RIA(Rich Internet Applications)技术,极大的完善了 Web 的用户体验,比如 Ajax。

  6. 移动 Web 应用阶段
    这个阶段出现了大量面向移动设备的 Web 应用技术,除了 IOS、Android 等操作系统平台原声的开发技术外,基于 H5 的开发技术越来越流行。

web 技术结构基石

  1. URI

  2. HTTP

  3. HTML

  4. MIME

REST 介绍

REST(Representational State Transfer, 表现层状态转换)软件架构是由 Roy Thomas Fielding 博士在 2000 年首次提出的。他为我们描绘了开发基于互联网的网络软件的蓝图。REST 软件架构是一个抽象的概念,是一种为了实现这一互联网的超媒体分布式系统的行动指南。

REST 是目前世界上最成功的分布式应用架构风格(Web),
REST 是所有 Web 应用都应该遵守的架构指导原则,违反了 REST
的指导原则,网站应用功能仍能实现,但会付出很多代价,特别是
大流量的网站。

在不同阶段,REST 给我们不同的印象:

  • 没接触 REST 时,会认为 REST 是一个技术
  • 没有深入理解 REST,日常使用仅限于修改 REST 风格的 URI、增加 PUT、DELETE 操作等,会认为 REST 是一种具体的规范
  • 深入理解之后,会发现 REST 是一种内含丰富的架构风格

REST 的五个关键词

1. 资源(Resource)

资源是一种看待服务器的方式,服务器就是由很多离散的资源组成。资源是以名词为核心来组织的,首先关注的应该是名词。一个资源由一个或多个 URI 来标识,URI 也即是资源的名称,客户端对某个资源感兴趣即通过 URI 来交互。

2. 资源的表述(Representation)

资源表述是指某一个资源某个时刻的状态描述,用于在客户端和服务端转移。例如:HTML/XML/JSON/图片/音频都是资源表述的格式。在通常的 REST 开发下,一般使用 JSON 作为 HTTP 请求响应的资源表述。

3. 状态转移(State Transfer)

状态转移是指通过转移和操作资源的表述,来实现操作资源的目的。在 REST 开发下,通常使用 HTTP 的 GET/POST/PUT/DELETE 方法操作。

4. 统一接口(Uniform Interface)

REST 要求必须使用统一的接口来对资源进行操作。

REST 要求对资源执行的操作,操作语义必须在 HTPP 消息体之前的部分完全表达,不能将操作语义封装到消息体内部。这样做为了提高交互可见性,便于通信的中间件实现缓存和安全审核。

REST 是不依赖于任何协议的,但目前几乎所有的 REST 都是基于 HTTP 协议的。接口应该使用标准的 HTTP 方法如 GET,PUT 和 POST,并遵循这些方法的语义。

非 REST 的接口,1000 个人能写出 1000 个接口,例如对机器人的操作:
(1)/api/findRobots
(2)/api/robots/select
REST API:
 GET /rest/robots/{id} 查询一个机器人
 POST /rest/robots 新建一个机器人
 PUT /rest/robots/{id} 更新一个机器人
 DELETE /rest/robots/{id} 删除一个机器人

统一接口主要包括:
(1)7 个 HTTP 方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS
(2)HTTP 头信息(可自定义)
(3)HTTP 响应状态代码(可自定义)
(4)一套标准的内容协商机制
(5)一套标准的缓存机制
(6)一套标准的客户端身份认证机制

HTTP 方法幂等性
幂等是指一次或多次请求一个资源的时候,应该具有相同的副作用。
HTTP 方法安全性
安全是指对原有资源没有任何影响,安全性不代表请求一定不产生副作用。比如 GET 请求增加计数器,这种产生的副作用是服务端自作主张,服务端在设计的时候应该不让副作用太大,客户端可以这些请求不会产生副作用。

GET: 安全且幂等,用来获取资源表示
POST: 不安全且不幂等,用来创建资源或用于部分更新资源
PUT: 不安全且幂等,用替换的方式更新资源
DELETE: 不安全且幂等,用于删除一个资源

PUT 和 POST 的区别:
PUT 和 POST 最大的区别是 PUT 是幂等的,此外 PUT 需要完成的 URI。
PUT /rest/robots/ 是不会成功的,URI 不能定位到具体的资源
PUT /rest/robots/{1234} 是会成功的,如果存在,则更新这个 robots

5. 超文本驱动(Hypertext Driven)

2008.10.28Fielding 博士针对 REST 的滥用,发表了《REST API 必须是超文本驱动的》。他指出除非应用状态引擎是超文本驱动的,否则它就不是 RESTFUL。

超文本驱动是客户端不再需要将某些接口的 URI 硬编码在代码中,唯一需要存储的只是 API 的 HOST 地址,能够非常有效的降低客户端与服务端之间的耦合,服务端对 URI 的任何改动都不会影响到客户端的稳定。

REST 架构约束

1. 客户-服务器(Client-Server)

这个约束是基于客户端-服务器架构背后的原则—–关注点分离。通过分离用户界面和数据存储这两个关注点,提高了用户界面跨平台的可能性,通过简化服务器组件提高了其伸缩性。

2. 无状态(Stateless)

服务器不保存除单次请求外的通信状态,REST 要求状态要么被放入资源状态中,要么保存在客户端,从客户端发出的每个请求都包含了服务端所必须的信息。

无状态约束使服务器的变化对客户端不可见,因而在连续的请求中,客户端并不依赖于同一台服务器,一台服务器坏掉了,客户端感知不到。

3. 可缓存(Cachable)

互联网中的客户端和中间层服务器可以缓存响应。

因此响应必须直接或间接定义自身是否可被缓存,以免客户端使用过期的响应数据来发送其它请求。

良好的缓存策略可以有效减少客户端-服务器之间的交互,从而进一步提高系统的可伸缩性和性能。

4. 分层系统 (Layered system)

通过限制组件的行为(即,每个组件只能“看到”与其交互的紧邻层),将架构分解为若干等级的层。

客户端通常无法判断它是否是直接连接到后端服务器,还是中间服务器。

中间服务器可通过启用负载平衡,并通过提供共享高速缓存来提高系统的可扩展性。

当然也可以强制执行安全政策。

5. 统一接口 (Unitform interface)

如上
(1) 资源标志的唯一性
(2) 资源的自描述性
(3) 超媒体驱动型
(4) 消息的自描述性

6. 按需代码(可选)

支持通过下载并执行一些代码(例如 Java Applet、Flash 或 JavaScript),对客户端的功能进行扩展。

参考资料

  1. 百科-web
  2. 百科-rest
  3. Roy Thomas Fielding 博士论文地址