REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,能够下降开发的复杂性,提升系统的可伸缩性。REST提出了一些设计概念和准则:大理石构件html
一、网络上的全部事物都被抽象为资源(resource);json
二、每一个资源对应一个惟一的资源标识(resource identifier);restful
三、经过通用的链接器接口(generic connector interface)对资源进行操做;网络
四、对资源的各类操做不会改变资源标识;app
五、全部的操做都是无状态的(stateless)。less
须要注意的是,REST是设计风格而不是标准。REST一般基于使用HTTP,URI,和XML以及HTML这些现有的普遍流行的协议和标准。dom
传统的请求模式和REST模式的请求模式区别:ide
做用 | 传统模式 | 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 |
关于更多的REST信息,能够参考:http://zh.wikipedia.org/wiki/RESTpost
3.2的RESTFul支持更为灵活,你只须要把控制器继承Think\Controller\RestController便可。 继承RestController控制器后你的访问控制器就能够支持下面的一些功能:ui
- 支持资源类型自动检测;
- 支持请求类型自动检测;
- RESTFul方法支持;
- 能够设置容许的请求类型列表;
- 能够设置容许请求和输出的资源类型;
- 能够设置默认请求类型和默认资源类型;
例如:
namespace Home\Controller;
use Think\Controller\RestController;
class BlogController extends RestController{
}
继承了RestController后,你能够在你的控制器里面设置rest相关的属性参数,包括:allowMethod,defaultMethod,allowType,defaultType以及allowOutputType。
属性名 | 说明 | 默认值 |
---|---|---|
allowMethod | REST容许的请求类型列表 | array('get','post','put','delete') |
defaultMethod | REST默认请求类型 | get |
allowType | REST容许请求的资源类型列表 | array('html','xml','json','rss') |
defaultType | REST默认的资源类型 | html |
allowOutputType | REST容许输出的资源类型列表 | array( 'xml' => 'application/xml', 'json' => 'application/json','html' => 'text/html',) |
RESTFul方法的操做方法定义主要区别在于,须要对请求类型和资源类型进行判断,大多数状况下,经过路由定义能够把操做方法绑定到某个请求类型和资源类型。若是你没有定义路由的话,须要本身在操做方法里面添加判断代码,示例:
namespace Home\Controller;
use Think\Controller\RestController;
Class InfoController extends RestController {
Public function rest() {
switch ($this->_method){
case 'get': // get请求处理代码
if ($this->_type == 'html'){
}elseif($this->_type == 'xml'){
}
break;
case 'put': // put请求处理代码
break;
case 'post': // post请求处理代码
break;
}
}
}
在Rest操做方法中,可使用$this->_type获取当前访问的资源类型,用$this->_method获取当前的请求类型。
REST控制器类还提供了response方法用于REST输出: 用法以下:
$this->response($data,'json');
Response方法会自动对data数据进行输出类型编码,目前支持的包括xml/json/html
。
除了普通方式定义Restful操做方法外,系统还支持另一种自动调用方式,就是根据当前请求类型和资源类型自动调用相关操做方法。系统的自动调用规则是:
定义规范 | 说明 |
---|---|
操做名提交类型资源后缀 | 标准的Restful方法定义,例如 read_get_pdf |
操做名_资源后缀 | 当前提交类型和defaultMethod属性相同的时候,例如read_pdf |
操做名_提交类型 | 当前资源后缀和defaultType属性相同的时候,例如read_post |
要使用这种方式的前提就是不能为当前操做定义方法,这样在空操做的检查以前系统会首先按照上面的定义规范顺序检查是否存在方法定义,若是检测到相关的restful方法则再也不检查后面的方法规范,例如咱们定义了InfoController以下:
namespace Home\Controller;
use Think\Controller\RestController;
Class InfoController extends RestController {
protected $allowMethod = array('get','post','put'); // REST容许的请求类型列表
protected $allowType = array('html','xml','json'); // REST容许请求的资源类型列表
Public function read_get_html(){
// 输出id为1的Info的html页面
}
Public function read_get_xml(){
// 输出id为1的Info的XML数据
}
Public function read_xml(){
// 输出id为1的Info的XML数据
}
Public function read_json(){
// 输出id为1的Info的json数据
}
}
若是咱们访问的URL是:
http://www.domain.com/Info/read/id/1.xml
假设咱们没有定义路由,这样访问的是Info控制器的read操做,那么上面的请求会调用InfoController类的 read_get_xml
方法,而不是read_xml
方法,可是若是访问的URL是:
http://www.domain.com/Info/read/id/1.json
那么则会调用read_json方法。
若是咱们访问的URL是
http://www.domain.com/Info/read/id/1.rss
因为咱们不容许rss资源类型的访问,因此,调用的方法实际上是read_html方法。
咱们能够借助3.2的路由参数功能,来解决REST的路由定义问题。 例如,
'blog/:id'=>array('blog/read','status=1',array('ext'=>'xml','method'=>'get')),
上面的路由定义,把blog/5路由到了blog/read/id/5 而且,约束了后缀是xml 请求类型是get。 咱们还能够定义其余的路由参数,例如:
'blog/:id'=>array('blog/update','',array('ext'=>'xml','method'=>'put')),
为了确保定义不冲突,REST路由定义咱们一般改为下面的定义方式:
array('blog/:id','blog/read','status=1',array('ext'=>'xml','method'=>'get')),
array('blog/:id','blog/update','',array('ext'=>'xml','method'=>'put')),
这样就能够给相同的路由规则定义不一样的参数支持。定义了REST路由后,你的rest方法定义就不受任何约束,固然,若是路由定义的操做方法不存在的时候,系统默认的rest方法规范仍然会有效。