Introduction
REST全称是Representational State Transfer,即为含状态传输。是Roy Thomas Fielding在他2000年的博士论文中提出的。Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席。
REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML以及HTML这些现有的广泛流行的协议和标准。REST风格的基本准则如下:
1、网络上的所有事物都被抽象为资源(resource);
2、每个资源对应一个唯一的资源标识(resource identifier);
3、通过通用的连接器接口(generic connector interface)对资源进行操作;
4、对资源的各种操作不会改变资源标识;
5、所有的操作都是无状态的(stateless)。
REST本质上是含状态传输的Web服务,即将原本使用方法名来标识的操作用GET、PUT、DELETE、POST来代替。
(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。
用法
含状态传输的 Web 服务(也称为 RESTful Web API)是一个使用HTTP并遵循REST原则的Web服务。它从以下三个方面资源进行定义:
l 直观简短的资源地址:URI,比如:http://example.com/resources/。
l 传输的资源:Web服务接受与返回的互联网媒体类型,比如:JSON,XML ,YAML 等。
l 对资源的操作:Web服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)。
资源 | GET | PUT | POST | DELETE |
一组资源的URI,比如http://example.com/resources/ | 列出 URI,以及该资源组中每个资源的详细信息(后者可选)。 | 使用给定的一组资源替换当前整组资源。 | 在本组资源中创建/追加一个新的资源。 该操作往往返回新资源的URL。 | 删除 整组资源。 |
单个资源的URI,比如http://example.com/resources/142 | 获取 指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:XML、JSON等) | 替换/创建 指定的资源。并将其追加到相应的资源组中。 | 把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。 | 删除 指定的元素。 |
具体的项目开发中,其应用如下:
作用 | 传统模式 | REST模式 |
列举出所有的用户 | GET /users/list | GET /users |
列出ID为1的用户信息 | GET /users/show/id/1 | GET /users/1 |
插入一个新的用户 | POST /users/add | POST /users |
更新ID为1的用户信息 | POST /users/mdy/id/1 | PUT /users/1 |
删除ID为1的用户 | POST /users/delete/id/1 | DELETE /users/1 |
优势
l 可更高效利用缓存来提高响应速度
l 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
l 浏览器即可作为客户端,简化软件需求
l 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
l 不需要额外的资源发现机制
l 在软件技术演进中的长期的兼容性更好
设计规范
非动作
REST的设计规范中不应包含动词,因为"资源"表示一种实体,所以应该是名词,URI不应该有动词,动词应该放在HTTP协议中。举例来说,某个URI是/posts/show/1,其中show是动词,这个URI就设计错了,正确的写法应该是/posts/1,然后用GET方法表示show。
如果某些动作是HTTP动词表示不了的,你就应该把动作做成一种资源。比如网上汇款,从账户1向账户2汇款500元,错误的URI是:
POST /accounts/1/transfer/500/to/2
正确的写法是把动词transfer改成名词transaction,资源不能是动词,但是可以是一种服务:
POST /transaction HTTP/1.1
Host: 127.0.0.1
from=1&to=2&amount=500.00
Versioning REST Services
创建Web Services时,可能需要面对版本变更或者返回类型的问题。因为不同的版本仍然是属于同种资源,应该还是指向同一个URI,那么版本号或者返回的文件类型不应该写在URI中。对于版本号或者返回的文件类型等相关信息可以写在HTTP 的Accept或者Content-Type中。譬如如果你的web service版本或者返回数据格式有如下几种:
n 1.0: vnd.example-com.foo+json; version=1.0
n 1.1: vnd.example-com.foo+json; version=1.1
n 2.0: vnd.example-com.foo+json; version=2.0
那么在客户端可以使用如下请求方式:
$.ajax({
beforeSend: function (req) {
req.setRequestHeader("Accept", "vnd.example-com.foo+json; version=1.1");
},
type: "GET",
url: "http://http://www.example.com/foo/12",
success: function (data) {
/* code elided */
},
dataType: "json"
});
在服务端处理请求时,注意要在返回头上加上:
Vary: Content-Type
这样你的Internet架构才能缓存你的请求。
参考资料
【1】http://zh.wikipedia.org/wiki/REST
【2】http://www.ruanyifeng.com/blog/2011/09/restful.html