在 Windwos 10 下 基于 Yii2 高级应用模板,实现 RESTful Web 服务的流程
1、请先参考上一篇博客:http://www.shuijingwanwq.com/2016/11/26/1436/
2、准备基于 shujujiexi 实现 RESTful Web 服务
3、基于 frontend 应用上的 Gii 生成模型,编辑\environments\dev\frontend\config\main-local.php,如图1
$config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => 'yii\gii\Module', 'allowedIPs' => ['127.0.0.1', '::1'], ];
4、在 Windows PowerShell 中执行 .\init,以覆盖\frontend\config\main-local.php,设置 Gii 允许访问的IP,如图2
5、打开网址:http://www.kaiqiu_shujujiexi_api.dev/index.php?r=gii,可以访问 Gii 了,如图3
6、编辑\frontend\config\main.php,以支持网址美化,如图4
'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ ], ],
7、打开网址:http://www.kaiqiu_shujujiexi_api.dev/gii,如图5
8、基于数据库表kq_schedule建立相应模型,如图6
9、点击Model Generator下的Start按钮,生成模型Schedule,命名空间为common\models,以便于后期其他应用皆可以使用此模型,此时无需支持国际化,如图7
10、点击 Generate 按钮,生成模型文件\common\models\Schedule.php,如图8
11、创建一个控制器\shujujiexi\controllers\ScheduleController.php,如图9
<?php namespace shujujiexi\controllers; use yii\rest\ActiveController; class ScheduleController extends ActiveController { public $modelClass = 'common\models\Schedule'; }
12、配置URL规则,修改urlManager组件的配置,如图10
'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ [ 'class' => 'yii\rest\UrlRule', 'controller' => 'schedule', ], ], ],
13、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应,如图11
14、为了在shujujiexi应用中实现自身的业务逻辑,建议新建\shujujiexi\models\Schedule.php,其继承至\common\models\Schedule,如图12
15、编辑控制器\shujujiexi\controllers\ScheduleController.php,重新指定模型为shujujiexi\models\Schedule,如图13
16、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应,如图11
17、在Postman中PUT:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules/1,正确响应,如图14
18、配置 only 和 except 选项来明确列出哪些行为支持, 哪些行为禁用。例如,只让其支持GET列表,则可以修改urlManager组件的配置,如图15
'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ [ 'class' => 'yii\rest\UrlRule', 'controller' => 'schedule', 'only' => ['index'], ], ], ],
19、在Postman中PUT:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules/1,404响应,如图16
20、基于URL规则:’GET,HEAD users’ => ‘user/index’,,在Postman中HEAD:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,空响应,可以不用理会,其他请求皆为404,如图17
21、对于404响应格式为HTML的解决,编辑\shujujiexi\config\main.php,设置默认的响应格式为JSON,如图18
'response' => [ 'format' => yii\web\Response::FORMAT_JSON, ],
22、再次执行第19项,404响应,其格式为JSON,如图19
23、数据序列化的实现,在响应主体内包含分页信息来 简化客户端的开发工作,编辑\shujujiexi\controllers\ScheduleController.php,如图20
public $serializer = [ 'class' => 'yii\rest\Serializer', 'collectionEnvelope' => 'items', ];
24、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应,在响应主体内包含分页信息,如图21
25、RESTful APIs 通常是无状态的,因此,配置user 应用组件,编辑\shujujiexi\config\main.php,如图22
'user' => [ 'identityClass' => 'common\models\User', 'enableAutoLogin' => false, 'identityCookie' => ['name' => '_identity-shujujiexi', 'httpOnly' => true], 'enableSession' => false, 'loginUrl' => null, ],
26、版本化的实现,新建目录\shujujiexi\modules,其结构如图23
27、\shujujiexi\modules\v1\Module.php,其内容,如图24
28、\shujujiexi\modules\v1\controllers\ScheduleController.php,其内容,如图25
29、\shujujiexi\modules\v1\models\Schedule.php,其内容,如图26
30、配置URL规则,修改urlManager组件的配置,如图27
31、配置模块规则,如图28
'modules' => [ 'v1' => [ 'basePath' => '@app/modules/v1', 'class' => 'shujujiexi\modules\v1\Module' ], ],
31、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,404响应,符合预期,如图29
32、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules,正确响应,如图30
33、响应数据的结构调整,默认为code、message、data字段
34、复制\vendor\yiisoft\yii2\rest\Serializer.php为\shujujiexi\rests\Serializer.php,其内容,继承至\yii\rest\Serializer,且只保留serializeDataProvider(),如图31
<?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace shujujiexi\rests; use Yii; /** * Serializer converts resource objects and collections into array representation. * * Serializer is mainly used by REST controllers to convert different objects into array representation * so that they can be further turned into different formats, such as JSON, XML, by response formatters. * * The default implementation handles resources as [[Model]] objects and collections as objects * implementing [[DataProviderInterface]]. You may override [[serialize()]] to handle more types. * * @author Qiang Xue <qiang.xue@gmail.com> * @since 2.0 */ class Serializer extends \yii\rest\Serializer { /** * Serializes a data provider. * @param DataProviderInterface $dataProvider * @return array the array representation of the data provider. */ protected function serializeDataProvider($dataProvider) { if ($this->preserveKeys) { $models = $dataProvider->getModels(); } else { $models = array_values($dataProvider->getModels()); } $models = $this->serializeModels($models); if (($pagination = $dataProvider->getPagination()) !== false) { $this->addPaginationHeaders($pagination); } if ($this->request->getIsHead()) { return null; } elseif ($this->collectionEnvelope === null) { return $models; } else { $result = [ $this->collectionEnvelope => $models, ]; if ($pagination !== false) { return ['code' => '00000', 'message' => 'success', 'data' => array_merge($result, $this->serializePagination($pagination))]; // return array_merge($result, $this->serializePagination($pagination)); } else { return ['code' => '00000', 'message' => 'success', 'data' => $result]; // return $result; } } } }
35、编辑控制器\shujujiexi\controllers\ScheduleController.php,如图32
36、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules,正确响应,如图33
37、如何自由定义此请求的响应的实现流程,分析\vendor\yiisoft\yii2\rest\ActiveController.php可发现,Index操作默认实现类为yii\rest\IndexAction,如图34
38、复制\vendor\yiisoft\yii2\rest\IndexAction.php至\shujujiexi\rests\schedule\IndexAction.php,如图35
39、编辑控制器\shujujiexi\controllers\ScheduleController.php,如图36
public function actions() { $actions = parent::actions(); $actions['index']['class'] = 'shujujiexi\rests\schedule\IndexAction'; return $actions; }
40、编辑\shujujiexi\rests\schedule\IndexAction.php,如图37
<?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace shujujiexi\rests\schedule; use Yii; use yii\rest; use yii\data\ActiveDataProvider; /** * @author Qiang Xue <qiang.xue@gmail.com> * @since 2.0 */ class IndexAction extends rest\IndexAction { /** * @var callable a PHP callable that will be called to prepare a data provider that * should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead. * The signature of the callable should be: * * ```php * function ($action) { * // $action is the action object currently running * } * ``` * * The callable should return an instance of [[ActiveDataProvider]]. */ /** * Prepares the data provider that should return the requested collection of the models. * @return ActiveDataProvider */ protected function prepareDataProvider() { if ($this->prepareDataProvider !== null) { return call_user_func($this->prepareDataProvider, $this); } /* @var $modelClass \yii\db\BaseActiveRecord */ $modelClass = $this->modelClass; return new ActiveDataProvider([ 'query' => $modelClass::find()->where(['status' => 1]), ]); } }
41、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules,正确响应,且仅返回status为1的数据,如图38
备注:
1、基于 Gii 生成的模型文件存放于common目录;
2、v1,控制器与模型中的方法建议在\shujujiexi\controllers、\shujujiexi\models中实现;
3、v2,如果需要有不同的功能实现,控制器与模型中的方法建议在\shujujiexi\modules\v1\controllers、\shujujiexi\modules\v1\models中覆盖实现;
4、shujujiexi\rests,其目录结构类似于shujujiexi\views,每一个控制器有其对应的目录;
5、在每一个主要版本 (在相应的模块),使用 Accept HTTP 请求头 确定小版本号编写条件代码来响应相应的次要版本;
// 通过参数
Accept: application/json; version=1.0.0
1 条回复
[…] […]