In Yii 2.0, based on the RESTful APIs on the desktop application side, the realization of multiplexing and overriding fine-tuning on the mobile application side (1)
1. Open the desktop application terminal, the interface, as shown in Figure 1
2. Interface: my topic selection (get a list of topics), the response structure in postman, as shown in Figure 2
3. Prototype design on the mobile application side, as shown in Figure 3
4. At this stage: the subsequent iterative development stage, the desktop side and the mobile terminal, in the same interface: my topic selection (obtaining the topic list), there will inevitably be certain differences, so it is decided to plan the corresponding route and the corresponding action respectively. Input files, however, in most interfaces in the current stage/substance iterative development stage, the desktop side is exactly the same as the mobile terminal. Therefore, it is hoped that the implementation in the action can be reused, and the fine-tuning is only covered when there is a difference. Its philosophy can be referenced (separate sites for mobile and desktop):https://developer.mozilla.org/en-US/docs/Web/Guide/Mobile/Separate_sites, openhttp://m.youtube.com/, the display on the desktop and mobile terminals (will automatically judge the request side, if it is the desktop side, it will automatically jump to:https://www.youtube.com/), as shown in Figure 4, Figure 5
5. The configuration of the urlmanager application component, \api\config\urlmanager.php
yii\web\UrlManager::class,
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/user'],
],
/* 选题管理 */
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/plan'],
'only' => ['index', 'create', 'view', 'update', 'delete', 'have', 'wait-review', 'cmc-group', 'edit', 'submit', 'refuse', 'pass', 'return', 'disable', 'enable', 'invite', 'invite-accept'],
'tokens' => ['{id}' => ''],
'extraPatterns' => [
'GET have' => 'have',
'GET wait-review' => 'wait-review',
'GET cmc-group/{id}' => 'cmc-group',
'GET edit/{id}' => 'edit',
'PUT submit/{id}' => 'submit',
'PUT refuse/{id}' => 'refuse',
'PUT pass/{id}' => 'pass',
'PUT return/{id}' => 'return',
'PUT disable/{id}' => 'disable',
'PUT enable/{id}' => 'enable',
'POST invite/{id}' => 'invite',
'PUT invite-accept/{id}' => 'invite-accept',
],
],
],
];
6. Controller class: \API\Controllers\planController.php, declared through the actions() method
'api\rests\plan\Serializer',
'collectionEnvelope' => 'items',
];
/**
* @inheritdoc
*/
public function actions()
{
$actions = parent::actions();
// 禁用"options"动作
unset($actions['options']);
$actions['index']['class'] = 'api\rests\plan\IndexAction';
$actions['create']['class'] = 'api\rests\plan\CreateAction';
$actions['view']['class'] = 'api\rests\plan\ViewAction';
$actions['update']['class'] = 'api\rests\plan\UpdateAction';
$actions['delete']['class'] = 'api\rests\plan\DeleteAction';
$actions['have'] = [
'class' => 'api\rests\plan\HaveAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['wait-review'] = [
'class' => 'api\rests\plan\WaitReviewAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['cmc-group'] = [
'class' => 'api\rests\plan\CmcGroupAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['edit'] = [
'class' => 'api\rests\plan\EditAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['submit'] = [
'class' => 'api\rests\plan\SubmitAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['refuse'] = [
'class' => 'api\rests\plan\RefuseAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['pass'] = [
'class' => 'api\rests\plan\PassAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['return'] = [
'class' => 'api\rests\plan\ReturnAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['disable'] = [
'class' => 'api\rests\plan\DisableAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['enable'] = [
'class' => 'api\rests\plan\EnableAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['invite'] = [
'class' => 'api\rests\plan\InviteAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
$actions['invite-accept'] = [
'class' => 'api\rests\plan\InviteAcceptAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
return $actions;
}
}
7. Use the module to isolate the code of different versions, \API\modules\v1\Controllers\PlanController.php
8. Action file: \API\RESTS\PLAN\HaveAction.php Inherited to \yii\rest\ActiveController Default provided action: \yii\rest\indexAction
* @since 1.0
*/
class HaveAction extends \yii\rest\IndexAction
{
public $dataFilter = [
'class' => 'yii\data\ActiveDataFilter',
'searchModel' => 'api\models\PlanSearch',
'attributeMap' => [
'created_at' => '{{%plan}}.[[created_at]]',
'status' => '{{%plan}}.[[status]]',
'title' => '{{%plan}}.[[title]]',
],
];
/**
* Prepares the data provider that should return the requested collection of the models.
* @return ActiveDataProvider
* @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]].
* @throws UnprocessableEntityHttpException
*/
protected function prepareDataProvider()
{
$requestParams = Yii::$app->getRequest()->getBodyParams();
if (empty($requestParams)) {
$requestParams = Yii::$app->getRequest()->getQueryParams();
}
$filter = null;
if ($this->dataFilter !== null) {
$this->dataFilter = Yii::createObject($this->dataFilter);
if ($this->dataFilter->load($requestParams)) {
$filter = $this->dataFilter->build();
if ($filter === false) {
$firstError = '';
foreach ($this->dataFilter->getFirstErrors() as $message) {
$firstError = $message;
break;
}
throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '224003'), ['first_error' => $firstError])), 224003);
}
}
}
if ($this->prepareDataProvider !== null) {
return call_user_func($this->prepareDataProvider, $this, $filter);
}
// 当前用户的身份实例,未认证用户则为 Null
/* @var $identity RedisCmcConsoleUser */
$identity = Yii::$app->user->identity;
/* @var $modelClass Plan */
$modelClass = $this->modelClass;
/* @var $haveQuery PlanQuery */
// 获取查询对象(我的选题(获取选题列表))
$haveQuery = $modelClass::getHaveQuery($identity);
$query = $haveQuery->orderBy([$modelClass::tableName() . '.id' => SORT_DESC]);
if (!empty($filter)) {
$query->andFilterWhere($filter);
}
return Yii::createObject([
'class' => ActiveDataProvider::className(),
'query' => $query,
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
]);
}
}
9. Due to the same interface, its business logic is basically the same, and the implementation of business logic exists in the directory: \common\models, \co Mmon\logics, \common\services, \api\models, \api\services. Therefore, there is no need to distinguish based on modules, it can be implemented based on the subdirectories of the controller. Create a new mobile directory: \api\controllers\mobile, copy \api\controllers\plancontroller.php to \API\Controllers\Mobile\PlanController.php
10. The configuration of the urlmanager application component, \api\config\urlmanager.php, added: mobile terminal – topic selection
/* 移动端 */
// 移动端 - 选题
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/mobile/plan'],
'only' => ['index', 'create', 'view', 'update', 'delete', 'have', 'wait-review', 'cmc-group', 'edit', 'submit', 'refuse', 'pass', 'return', 'disable', 'enable', 'invite', 'invite-accept'],
'tokens' => ['{id}' => ''],
'extraPatterns' => [
'GET have' => 'have',
'GET wait-review' => 'wait-review',
'GET cmc-group/{id}' => 'cmc-group',
'GET edit/{id}' => 'edit',
'PUT submit/{id}' => 'submit',
'PUT refuse/{id}' => 'refuse',
'PUT pass/{id}' => 'pass',
'PUT return/{id}' => 'return',
'PUT disable/{id}' => 'disable',
'PUT enable/{id}' => 'enable',
'POST invite/{id}' => 'invite',
'PUT invite-accept/{id}' => 'invite-accept',
],
],
11. Controller class: \API\Controllers\Mobile\PlanController.php, inherited to:\API\Controllers\PlanController, declare through the actions() method, overwrite the method class file
'api\rests\mobile\plan\Serializer',
'collectionEnvelope' => 'items',
];
/**
* @inheritdoc
*/
public function actions()
{
$actions = parent::actions();
$actions['index']['class'] = 'api\rests\mobile\plan\IndexAction';
$actions['create']['class'] = 'api\rests\mobile\plan\CreateAction';
$actions['view']['class'] = 'api\rests\mobile\plan\ViewAction';
$actions['update']['class'] = 'api\rests\mobile\plan\UpdateAction';
$actions['delete']['class'] = 'api\rests\mobile\plan\DeleteAction';
$actions['have']['class'] = 'api\rests\mobile\plan\HaveAction';
$actions['wait-review']['class'] = 'api\rests\mobile\plan\WaitReviewAction';
$actions['cmc-group']['class'] = 'api\rests\mobile\plan\CmcGroupAction';
$actions['edit']['class'] = 'api\rests\mobile\plan\EditAction';
$actions['submit']['class'] = 'api\rests\mobile\plan\SubmitAction';
$actions['refuse']['class'] = 'api\rests\mobile\plan\RefuseAction';
$actions['pass']['class'] = 'api\rests\mobile\plan\PassAction';
$actions['return']['class'] = 'api\rests\mobile\plan\ReturnAction';
$actions['disable']['class'] = 'api\rests\mobile\plan\DisableAction';
$actions['enable']['class'] = 'api\rests\mobile\plan\EnableAction';
$actions['invite']['class'] = 'api\rests\mobile\plan\InviteAction';
$actions['invite-accept']['class'] = 'api\rests\mobile\plan\InviteAcceptAction';
return $actions;
}
}
12. Use the module to isolate the code of different versions, copy \api\modules\v1\controllers\plancontroller.php to \API\modules\v1\Controllers\Mobile\PlanController.php, which inherits to \API\Controllers\Mobile\PlanController
13. Copy \API\RESTS\PLAN to \API\RESTs\Mobile\Plan, and replace the namespace in batches, as shown in Figure 6
14. Edit the action file:\api\rests\mobile\plan\haveaction.php, inherit to \API\RESTS\PLAN\HaveAction, since there is no difference between the mobile terminal and the desktop side of this interface, the run() method in the file can be deleted
15. Convert the resource object to an array, edit the data serialization file: \api\rests\mobile\plan\serializer.php, inherit to \API\RESTS\PLAN\Serializer, since there is no difference between the mobile terminal and the desktop side of this interface, so the SerializeDataProvider() method in the file can be deleted
16. Open the desktop interface in Postman, as shown in Figure 7
17. Open the mobile terminal interface in Postman, as shown in Figure 8
18. If there is a difference between the mobile terminal and the desktop side of this interface, the run() method can be overwritten and adjusted. In the follow-up, we will try to extract some reusable codes in the run() method and implement them as a method (placed in the file: \API\RESTS\PLAN\HaveAction.php).







