HTTP & RESTful

HyperText Transfer Protocol & REpresentational State Transfer

一、概述#

超文本传输协议(HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。

表现层状态转换(REST)本身并没有创造新的技术、组件或服务,而隐藏在 RESTful 背后的理念就是使用 Web 的现有特征和能力, 更好地使用现有 Web 标准中的一些准则和约束。虽然 REST 本身受 Web 技术的影响很深, 但是理论上 REST 架构风格并不是绑定在 HTTP 上,只不过目前 HTTP 是唯一与 REST 相关的实例。

1.1 URI#

统一资源标识符Uniform Resource Identifier,URI)是一个用于标识某一互联网资源名称的字符串。URI的最常见的形式是统一资源定位符Uniform Resource Locator,URL),经常指定为非正式的网址。更罕见的用法是统一资源名称(Uniform Resource Name,URN),其目的是通过提供一种途径。用于在特定的名字空间资源的标识,以补充网址。在RESTful架构中 URI 不应该有动词,动词应该放在HTTP协议中

资源是一种信息实体,它可以有多种外在表现形式。“资源” 具体呈现出来的形式,叫做它的 “表现层”(Representation)。URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的 “.html” 后缀名是不必要的,因为这个后缀名表示格式,属于 “表现层” 范畴,而 URI 应该只代表 “资源” 的位置。它的具体表现形式,应该在 HTTP 请求的头信息中用 AcceptContent-Type 字段指定,这两个字段才是对 “表现层” 的描述。

因为不同的版本,可以理解成同一种资源的不同表现形式,所以应该采用同一个 URI。版本号可以在 HTTP 请求头信息的 Accept 字段中进行区分(参见Versioning REST Services ):

1.2 如何理解 RESTful#

REST 本身受 Web 技术的影响很深,可以借助 WEB 来理解 RESTful。网站是采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点的一种软件。表现层(Representation)的含义是把资源具体的形式呈现出来。表现层上的网站交互就是客户端获取或修改服务器端储存的资源,而这些获取或修改的操作就是资源的状态转换。具体的实现很简单

  • 名词URL)表示资源
  • 动词GET / POST / PUT / DELETE)表示对资源状态的转换

比如在使用 spring boot 实现一个 WEB 应用时:

// 查询所有记录
@RequestMapping(value = "/users", method = RequestMethod.GET)
@ResponseBody
public Result<List<User>> queryAll() {
    
}

// 新增一条记录
@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public Result<Boolean> insert(@RequestBody User user) {
    
}

// 修改一条记录
@RequestMapping(value = "/users", method = RequestMethod.PUT)
@ResponseBody
public Result<Boolean> update(@RequestBody User tempUser) {
    
}

对于同一个 URL ,即同一个资源,通过不同的请求来改变资源状态。

二、请求#

客户端发送的 请求报文 第一行为请求行,包含了方法字段。

RESTful 架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的 HTTP 方法如 GET,PUT 和 POST,并遵循这些方法的语义。如果按照 HTTP 方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性:

  • 安全性:无论请求多少次,都不会改变服务器状态;
  • 幂等性:无论对资源操作多少次, 结果总是一样的,后面的请求并不会产生比第一次更多的影响。
HTTP 方法 作用 Idempotent Safe 备注
OPTIONS 查询支持的方法 yes yes 查询指定的 URL 能够支持的方法
GET 获取资源 yes yes 网络请求中,绝大部分使用的是 GET 方法
HEAD 获取报文首部 yes yes 主要用于确认 URL 的有效性以及资源更新的日期时间等
PUT 上传文件 yes no 不带验证机制
POST 传输实体主体 no no PUT 和 DELETE 不可缓存,POST 在多数情况下不可缓存
DELETE 删除文件 yes no 不带验证机制
PATCH 对资源进行部分修改 no no PUT 用于完全代替;PATCH 用于部分修改

客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

三、响应#

服务器返回的 响应报文 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,必然涉及到数据和状态的变化。状态码及其含义如下:


状态码 类别 含义
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错

3.1 避免返回纯文本#

API 返回的数据格式,不应该是纯文本,而应该是一个 JSON 对象,因为这样才能返回标准的结构化数据。所以,服务器回应的 HTTP 头的Content-Type属性要设为application/json

客户端请求时,也要明确告诉服务器,可以接受 JSON 格式,即请求的 HTTP 头的ACCEPT属性也要设成application/json

GET /orders/2 HTTP/1.1 
Accept: application/json

3.2 提供链接#

API 的使用者未必知道,URL 是怎么设计的。一个解决方法就是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL。这种方法叫做 HATEOAS。

参考#

  1. RESTful 中文网
  2. 阮一峰-理解RESTful架构
  3. 阮一峰-RESTful API 最佳实践
  4. 上野宣. 图解 HTTP[M]. 人民邮电出版社, 2014.
  5. HTTP 首部字段
  6. HATEOAS

2019-2021 © lil-q