REST 一词,是由 HTTP 协议的主要设计者 Roy Fielding 在他 2000 年的博士论文中提出的。git
论文地址:https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htmgithub
在这篇论文中,Roy Fielding 阐述了一种 Web 软件的架构风格(Architectural Style),并将其命名为 REST,即 Representational State Transfer(表征性状态转移) 的缩写。web
论文中描述了 REST 的六大软件工程原则,符合这些原则的架构被称为 RESTful 架构。数据库
C/S架构。api
无状态:服务端不记录客户端的状态,客户端的每次请求中都必须包含充分的信息,以便于服务端可以识别客户端的状态。缓存
统一的接口服务器
可缓存:客户端容许缓存服务端响应的内容。网络
系统分层:在终端服务器与客户端之间容许存在中间层(如代理服务器)。架构
按需编码(可选):服务端能够经过给客户端返回一段功能代码(如 Javascript 代码)让客户端来执行,从而实现某些特定的功能。编辑器
做为 HTTP 协议的主要设计者,Roy Fielding 提出的 REST 架构风格偏偏是对 HTTP 协议的提倡与使用指导。HTTP 协议自己是一种面向资源的应用层协议,可是开发者们对 HTTP 的使用方式并不统一,不少 Web 服务的开发者们都并无彻底把 HTTP 看成应用层协议,而只是把它当作传输层协议来用,而后在 HTTP 之上又创建起了本身的应用层协议。这是 Roy Fielding 不但愿看到的。
他倡导开发者们充分利用 HTTP 协议的特性(例如使用 HTTP Method 来指定对目标资源的操做)、听从 HTTP 设计思想来开发 Web 服务。
从某种意义上来讲,REST 架构风格就是听从了 HTTP 设计思想的 Web 架构风格。
RESTful 是 “REST” 的形容词形式,即“符合 REST 架构风格的”。符合 REST 架构风格的架构称为 RESTful 架构;符合 REST 架构风格的 Web 服务称为 RESTful Web 服务;符合 REST 架构风格的 Web API 称为 RESTful API。
Python 爬虫库 BeautifulSoup 的做者 Leonard Richardson 提出了一个成熟度模型,该模型把 RESTful Web 服务按照成熟度划分红 4 个层次:
URI 中尽可能使用名词,原则上不使用动词,即 URI 仅用做对资源的标识。
经过 HTTP Method 来指定对资源的操做。如 GET 表示获取资源、POST 表示新建资源、PUT 表示全局更新资源(须要在请求体中包含完整的目标资源的表现层,于是不推荐使用),PATCH 表示局部更新资源,DELETE 表示删除资源。
URI 中的名词通常采用复数形式,表示某类资源的集合,如 /tickets
表示所有 ticket 的集合。
若是要表示集合中的单个资源,就在后面拼接这个资源的ID。如 /tickets/12
,表示 ID 为12的那个 ticket。
使用QueryString筛选集合中的元素,如 /tickets?status=1&sum>=100
,表示状态为1且金额>=100的 ticket 的集合。
经过 URI 的层层递进来创建资源的父子关系,如 /tickets/12/collections/3
,表示 ID 为12的那个 ticket 下的 ID 为3的 collection。
使用形容词来定制对某类资源的查询结果,如 /tickets/recently_closed
表示最近关闭的 ticket 的集合,/tickets/a_specialized
表示专门给a定制的 ticket 的集合。
为了支持复杂查询,建议提供 /queries
,当客户端须要传递的参数过多时,容许客户端 POST /queries
,将查询参数放在请求体中传递过去, /queries
服务负责将请求体映射成一个 query 实体并写入数据库,而后返回 query_id。客户端拿到 query_id 后再 GET /tickets?query_id=111
。
关于分页,HTTP 推荐将分页信息放在 Link
响应头中,参考 GitHub API 的设计,以下:
Link: <https://api.github.com/user/repos?page=3&per_page=100>; rel="next",<https://api.github.com/user/repos?page=2&per_page=100>; rel="pre",<https://api.github.com/user/repos?page=1&per_page=100>; rel="first",<https://api.github.com/user/repos?page=50&per_page=100>; rel="last",
101 Switching Protocols:表示须要切换网络协议,此时客户端应当断开 HTTP 链接,使用指定的协议从新与服务端创建链接。
200 OK:表示一切正常。
201 Created :表示资源已成功建立,新资源的 URL 位于 Location
响应头中,用户能够选择在须要的时候访问它。
301 Moved Permanently:表示目标资源被永久转移,新的 URL 位于 Location
响应头中,此时客户端应当对新的 URL 发起请求。
302 Found:表示目标资源被临时转移,新的 URL 位于 Location
响应头中,此时客户端应当对新的 URL 发起请求。
303 See Other:表示请求已被处理,但未返回处理结果,此时客户端应当请求另外一个资源来获取处理结果,该资源的 URL 位于 Location
响应头中。
307 Temporary Redirect:表示请求还没有被处理,是由于请求的资源不在本地,而在另外一个 URL 处,客户端应当对那个 URL 发起请求,该 URL 位于 Location
响应头中。
307 与 303 的区别:对于 GET 请求来讲,307 与 303 没有区别,对于 POST、PUT、DELETE 请求来讲,它们的区别在于,307 说明请求的操做还没有执行,而 303 说明请求的操做已经执行过了。
400 Bad Request:表示用户发起的请求有问题,服务端没法处理该请求。
401 Unauthorized:表示用户对该资源的访问还没有获得受权。
403 Forbidden:表示用户无权访问该资源。
404 Not Found:表示目标资源不存在。
415 Unsupported Media Type:表示请求体的媒体类型与服务端所指望的不符。
429 Too Many Requests:表示用户请求的次数过多,超出了服务端的限速阈值。
500 Internal Server Error:表示服务端内部出现异常。
502 Bad Gateway:表示客户端代理方面出现异常。
503 Service Unavailable:表示服务端因繁忙或故障而拒绝本次服务,并经过响应头Retry-After告知客户端什么时候能够重试。