Restful整合到CI框架整理文件
RESTful
REST全名Representational State Transfer,中文可以译为:表现层状态转化,是一种网络服务的架构工具,而不仅仅是一套接口规范。
主要特点:
1.'使用名词而不是动词
你的RESTful接口应该提供访问而不是方法。
1 |
/createCustomer |
应该这样:
1 |
POST /customers |
2.'所有东西都应该有ID
REST的优点之一就是简洁,一定程度上来讲,REST只是一个URI的集合,每个资源都需要一个独一无二的ID作为一个标识。
1 2 |
GET /customers/666 GET /products/4234 |
|
3.'使用动词进行操作
在REST里,使用不同的HTTP动词进行增删改查的操作:
动词 |
操作 |
Post |
新建一个资源 |
Get |
读取一个资源 |
Put |
更新一个资源 |
Delete |
删除一个资源 |
Patch |
用来对已知资源进行局部更新 |
Head |
请求用于获取某个资源的元数据(metadata) |
Options |
请求用于获取某个资源所支持的Request类型 |
GET请求用于向Server端获取资源,而DELETE请求则用于删除Server端的某个资源。GET的Response一般包含资源的内容,而DELETE的Response可能包含一些状态信息(删除成功或者失败),也可能什么都不包含。
比如:GET /web/blog/3 这个请求会获取第三篇blog的内容,而DELETE /web/blog/3 这个请求则会删除第三篇blog。
PUT请求用于在Server端创建新的资源 (create),或者对已有资源进行修改 (modify)。PUT请求中一般会包含该新资源的内容。
比如:PUT /web/blog 这个请求会在Server端创建一个新的资源,资源名称是blog;而PUT /web/blog/3 这个请求则会修改第三篇blog(用新的内容来覆盖旧的)。
Post:方法用来创建一个子资源,如 /api/users,会在users下面创建一个user,如users/1
POST方法不是幂等的,多次执行,将导致多条相同的用户被创建(users/1,users/2 ...而这些用户除了自增长id外有着相同的数据,除非你的系统实现了额外的数据唯一性检查)
Patch: 用来对已知资源进行局部更新
而PUT方法用来创建一个URI已知的资源,或对已知资源进行完全替换,比如users/1,
因此PUT方法一般会用来更新一个已知资源,除非在创建前,你完全知道自己要创建的对象的URI。
'HEAD'和OPTIONS
HEAD请求用于获取某个资源的元数据(metadata)–比如,该资源是否存在,该资源的内容长度是多少等等。
OPTIONS请求用于获取某个资源所支持的Request类型,在OPTIONS请求的Response中会包含Allow头信息,比如:
Allow: GET HEAD
上述例子表示该资源只支持GET请求与HEAD请求。
'4.'使用状态码进行回复
HTTP的状态码提供了一套标准化方案,用来反馈请求的状态。
含义 |
解释 | |
---|---|---|
200 |
OK |
确认GET、PUT和DELETE操作成功 |
201 |
Created |
确认POST操作成功 |
304 |
Not Modified |
用于条件GET访问,告诉客户端资源没有被修改 |
400 |
Bad Request |
通常用于POST或者PUT请求,表明请求的内容是非法的 |
401 |
Unauthorized |
需要授权 |
403 |
Forbidden |
没有访问权限 |
404 |
Not Found |
服务器上没有资源 |
405 |
Method Not Allowed |
请求方法不能被用于请求相应的资源 |
409 |
Conflict |
访问和当前状态存在冲突 |
到这里,restful的基本特征就说完了,接下来,让我们看下CI框架里的restful的应用。
首先需要引入restful的类库。Restful类库主要是一些api访问约束,及接受参数和返回格式的格式规定。
[[File:]]
Restful类库是继承了CI的类库。
[[File:]]
此外,还需要为api的访问建立公用配置的config文件,用来定义访问的安全
级别和安全配置。
其他,详见案例:
require APPPATH.'/libraries/REST_Controller.php';
class Example_restful extends REST_Controller
{
public function __construct()
{
// Construct our parent class
parent::__construct();
// Configure limits on our controller methods. Ensure
// you have created the 'limits' table and enabled 'limits'
// within application/config/rest.php
$this->methods['user_get']['limit'] = 500; //500 requests per hour per user/key
$this->methods['user_post']['limit'] = 100; //100 requests per hour per user/key
$this->methods['user_delete']['limit'] = 50; //50 requests per hour per user/key
}
public function user_get()
{
if(!$this->get('id'))
{
$this->response(NULL, 400);
}
// $user = $this->some_model->getSomething( $this->get('id') );
$users = array(
1 => array('id' => 1, 'name' => 'Some Guy', 'email' => 'example1@example.com', 'fact' => 'Loves swimming'),
2 => array('id' => 2, 'name' => 'Person Face', 'email' => 'example2@example.com', 'fact' => 'Has a huge face'),
3 => array('id' => 3, 'name' => 'Scotty', 'email' => 'example3@example.com', 'fact' => 'Is a Scott!', array('hobbies' => array('fartings', 'bikes'))),
);
$user = @$users[$this->get('id')];
if($user)
{
$this->response($user, 200); // 200 being the HTTP response code
}
else
{
$this->response(array('error' => 'User could not be found'), 404);
}
}
function user_post()
{
//$this->some_model->updateUser( $this->get('id') );
$message = array('id' => $this->get('id'), 'name' => $this->post('name'), 'email' => $this->post('email'), 'message' => 'ADDED!');
$this->response($message, 200); // 200 being the HTTP response code
}
function user_delete()
{
//$this->some_model->deletesomething( $this->get('id') );
$message = array('id' => $this->get('id'), 'message' => 'DELETED!');
$this->response($message, 200); // 200 being the HTTP response code
}
function users_get()
{
//$users = $this->some_model->getSomething( $this->get('limit') );
$users = array(
array('id' => 1, 'name' => 'Some Guy', 'email' => 'example1@example.com'),
array('id' => 2, 'name' => 'Person Face', 'email' => 'example2@example.com'),
3 => array('id' => 3, 'name' => 'Scotty', 'email' => 'example3@example.com', 'fact' => array('hobbies' => array('fartings', 'bikes'))),
);
if($users)
{
$this->response($users, 200); // 200 being the HTTP response code
}
else
{
$this->response(array('error' => 'Couldn\'t find any users!'), 404);
}
}
public function send_post()
{
var_dump($this->request->body);
}
public function send_put()
{
var_dump($this->put('foo'));
}
}
模拟请求方法如下,仅以post/get方法进行介绍
<?php
/**
* Description of test
*
* @author yanyan.feng
*/
class Test extends MY_Controller {
public function __construct() {
parent::__construct ();
}
/**
* test restful post
*/
public function test_restful_post(){
$username = 'admin';
$email = 'test@qq.com';
$password = '1234';
//CI带的
// $this->load->library('curl');
// $this->curl->create('http://restful.fumubang.net/api/example_restful/user/id/1/format/json');
// //本行可选,如果你的RESTful API是开放的,则请删除该行 $this->curl->http_login($username, $password);
// $this->curl->post(array(
// 'name' => $username,
// 'email' => $email
// ));
// $result = json_decode($this->curl->execute());
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, 'http://restful.fumubang.net/api/example_restful/user/id/1/format/json');
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_POST, 1);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, array(
'name' => $username,
'email' => $email,
'city_id'=>'1',
'version'=>'2.1'
));
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);
var_dump($buffer);
// $result = json_decode($buffer);
// var_dump($result);
//rest客户端集成的
// $id=1;
// $this->load->library('rest', array(
// 'server' => 'http://restful.fumubang.net/api/example_restful/',
// 'http_user' => 'admin',
// 'http_pass' => '1234',
// 'http_auth' => 'basic' // 或者使用'digest'
// ));
// $user = $this->rest->get('user', array('id' => $id), 'json');
// print_r($user);
//echo $user->name;
}
}