阿江 2017-10-15 09:01:26 3271次浏览 0条回复 0 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-rest-controllers.html

本文主题:RESTful的控制器(Contorllers)

在创建资源类,并定义资源数据格式后,下一步要做的是创建控制器动作,通过RESTful API向终端用户开放资源。

Yii提供了两个基本的控制器类来简化创建RESTful动作:yii\rest\Controller和yii\rest\ActiveController。两个控制器的不同之处在于:后者为Active Record资源提供了一套默认动作。如果你使用Active Record,且内置动作能够满足你的要求,那么你的控制器类就可以从yii\rest\ActiveController继承,这样你可以使用最少的代码创建功能强大的RESTful API。

yii\rest\Controller和yii\rest\ActiveController具有以下特征,还在一些特征将在下几章节中叙述: 1、HTTP方法验证 2、内容协商和数据格式化 3、身份验证 4、频率限制

yii\rest\ActiveController还提供以下功能: 1、一套通用的必备动作:index、view、create、update、delete、options 2、请求动作和资源的用户授权

1、创建控制器类

当创建一个新的控制器类,关于控制器命名的约定是使用资源的类型名称,并且是单数形式。例如,提供用户信息,控制器的名称是UserController。

创建一个新的动作与Web应用中创建动作类似,唯有一点不同是:RESTful动作直接返回数据,而不是调用render()将数据渲染到视图中。serializer和response对象将处理从原始数据到请求格式的转换,例如:

public function actionView($id){
	return User::findOne($id);
}
2、过滤器(Filters)

Yii\rest\Controller实现的很多RESTful API特性都是以filters形式出现的,实际上,以下过滤器将按排列顺序去执行: contentNegotiator:支持内容协商,详情参见Resopnse Formatting章节:

http://www.yiiframework.com/doc-2.0/guide-rest-response-formatting.html

verbFilter:支持HTTP方法验证 authenticator:支持用户身份验证,详情参见Authentication章节:

http://www.yiiframework.com/doc-2.0/guide-rest-authentication.html

rateLimiter:支持请求频率限制,详情参见Rate Limiting章节:

http://www.yiiframework.com/doc-2.0/guide-rest-rate-limiting.html

这些过滤器都在behaviors()方法中声明,你可以重写这个方法以配置私有的过滤器,屏蔽一部分,或者添加你自己的过滤器,例如 ,你可能仅使用HTTP基本验证,你可以编写如下代码:

use yii\filters\auth\HttpBasicAuth;
public function behaviors(){
	$behaviors=parent::behaviors();
	$behaviors['authenticator']=[
		'class'	=> HttpBasicAuth::className(),
	];
	return $behaviors;
}
CORS

为控制器添加CORS(Cross-Origin Resource Sharing,跨域资源共享) 过滤器将比上面所述的过滤器要复杂一些,因为在身份验证之前就要应用CORS过滤器,这样就需要一个与其他过滤器略有不同的分支。对于CORS Preflight请求,身份验证必须被禁用,这样无需发送身份凭证浏览器就可以安全决定是否预先生成一个请求。为继承自yii\rest\ActiveController的控制器添加yii\filters\Cors过滤器的代码如下:

use yii\filters\auth\HttpBasicAuth;
public function behaviors(){
	$behaviors=parent::behaviors();
	//移去身份验证过滤器
	$auth=$behaviors['authenticator'];
	unset($behaviors['authenticator']);
	//添加CORS过滤器
	$behaviors['corsFilter']=[
		'class'	=>\yii\filters\Cors::className(),
	];
	//重新添加身份验证过滤器
	$behaviors['authenticator']=$auth;
	//在CORS-pre-flight请求中避免使用身份验证(HTTP OPTIONS方法)
	$behaviors['authenticator']['except']=['options'];
	return $behaviors;
}
3、扩展ActiveController

如果你的验证器继承自yii\rest\ActiveController,你可以设置它的modelClass属性为资源类名称,这样你可以通过这个控制器提供服务,这个类必须继承自yii\db\ActiveRecord。

Customizing Actions(自定义动作)

yii\rest\ActiveController默认提供以下的动作: index:分页列出资源 view:返回指定资源的详情页 create:创建一个新资源 update:更新一个已存在的资源 delete:删除指定的资源 options:返回支持的HTTP方法

所有的动作都使用actions()方法来声明,你可以通过重写actions()方法来重新定义或禁用这些动作,代码如下:

public function actions(){
	$actions=parent::actions();
	//禁用"delete"和"create"动作
	unset($actions['delete'],$actions['create']);
	//使用"prepareDataProvider()"方法自定义数据提供器
	$actions['index']['prepareDataProvider']=[$this,'prepareDataProvider'];
	return $actions;
}
public function prepareDataProvider(){
	//为index动作准备和返回一个数据提供器。
}

请查看私有动作类的类参考文档,以学习哪些配置选项是有效的。 如: D:\phpwork\advanced\vendor\yiisoft\yii2\rest\IndexAction.php

实例,更改数据提供器的方法

D:\phpwork\api\controllers\UserController.php

namespace app\controllers;
use yii\data\ActiveDataProvider;
use yii\rest\ActiveController;
use app\models\Users;
class UserController extends  ActiveController{
    public $modelClass='app\models\Users';
    public function actions() {
        $actions=parent::actions();
        $actions['index']['prepareDataProvider']=[$this,'prepareDataProvider'];
        return $actions;
    }
    public function prepareDataProvider(){
        return new ActiveDataProvider([
            'query'=>Users::find(),
            'pagination'=>[
                'defaultPageSize'=>2,
            ],
        ]);
    }
}
Performing Access Check(执行存取检查)

当通过RESTful API发布资源时,你常常需要检查当前用户是否有存取权限,并处理请求的资源。使用yii\rest\ActiveController,可以通过checkAccess()方法实现,代码如下:

public function checkAccess($action,$model=null,$params=[]){
	if($action==='update'||$action==='delete'){
		if($model->author_id!==Yii:$app->user->id){
			throw new \yii\web\ForbiddenHttpException(sprintf('You can only %s articles that you\'ve creted',$action));
		}
	}
}

checkAccess()方法将被yii\rest\ActiveController的默认动作调用。如果你创建一个新动作,并进行权限检测,你需要在新的动作中显式调用这个方法。

小贴士:你可以使用Role-Based Access Control(RBAC)组件实现checkAccess()。

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册