没有不值得去解决的问题,也没有不值得去学习的技术!

Code Review of RESTful API Material Implementation for Topic Selection Tasks in Yii 2.0

IDE prompt: non-controller class file

1. The requirements proposed for the new colleague to implement are as follows:

(1) Logged in, desktop
\api\rests\resource
Change to:
\api\rests\plan_task_resource

(2) Guest, no changes
\api\rests\client_resource

(3) Logged in, mobile
Task Management – Delete Task Material
Task Management – Admin Backend Material List
\api\rests\mobile\plan_task_resource

(4) Logged in, mobile
/v1/mobile/resources/resource
Material Upload
\api\rests\mobile\plan_task_resource

2. Code review, \api\config\urlManager.php, configuration: ‘controller’ => [‘v1/client-resource’], appears 2 times, the rule configuration is redundant, delete it (Client — Task Management – Material)

PHP

        // 客户端 - 素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/client-resource'],
            'tokens' => ['{id}' => ''],
            'extraPatterns' => [
                'POST resource' => 'create',
                'POST make-up' => 'makeup',
                'POST del-or-recovery' => 'del-or-recovery',
            ],
        ],

PHP

        // 客户端 -- 任务管理 - 素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/client-resource'],
            'only' => ['index', 'create', 'update', 'edit', 'list', 'delete'],
            'tokens' => ['{id}' => ''],
        ],

3. \api\config\urlManager.php, configuration: ‘controller’ => [‘v1/client-resource’], adjust the rule as follows (Standard: the pattern name and action name should be consistent, configure the only option to explicitly list the supported behaviors):
Adjust to:

PHP

        // 客户端 - 素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/client-resource'],
			'only' => ['resource', 'make-up', 'del-or-recovery'],
            'tokens' => ['{id}' => ''],
            'extraPatterns' => [
                'POST resource' => 'resource',
                'POST make-up' => 'make-up',
                'POST del-or-recovery' => 'del-or-recovery',
            ],
        ],

4. Controller: \api\controllers\ClientResourceController.php, the actions() method needs to be adjusted. yii\rest\ActiveController provides some default actions, and if they are not needed, they must be destroyed. When displaying data via RESTful APIs, it is often necessary to check whether the current user has permission to access and operate on the requested resource. In yii\rest\ActiveController, you can override the checkAccess() method to perform the permission check. Before and after =>, only a single space is needed; alignment is not required.

PHP

    /**
     * @inheritdoc
     */
    public function actions()
    {
        $actions = parent::actions();
        $actions['create'] = [
            'class'      => 'api\rests\client_resource\ResourceAction',
            'modelClass' => $this->modelClass,
        ];
        $actions['makeup'] = [
            'class'      => 'api\rests\client_resource\ResourceUpdateAction',
            'modelClass' => $this->modelClass,
        ];
        $actions['del-or-recovery'] = [
            'class'      => 'api\rests\client_resource\DelOrRecoveryAction',
            'modelClass' => $this->modelClass,
        ];
        return $actions;
    }

Adjust to:

PHP

    /**
     * @inheritdoc
     */
    public function actions()
    {
        $actions = parent::actions();
        // 禁用"index"、"view"、"create"、"update"、"delete"、"options"动作
        unset($actions['index'], $actions['view'], $actions['create'], $actions['update'], $actions['delete'], $actions['options']);
        $actions['resource'] = [
            'class' => 'api\rests\client_resource\ResourceAction',
            'modelClass' => $this->modelClass,
			'checkAccess' => [$this, 'checkAccess'],
        ];
        $actions['make-up'] = [
            'class' => 'api\rests\client_resource\ResourceUpdateAction',
            'modelClass' => $this->modelClass,
			'checkAccess' => [$this, 'checkAccess'],
        ];
        $actions['del-or-recovery'] = [
            'class' => 'api\rests\client_resource\DelOrRecoveryAction',
            'modelClass' => $this->modelClass,
			'checkAccess' => [$this, 'checkAccess'],
        ];
        return $actions;
    }

5. Controller in module v1: \api\modules\v1\controllers\ClientResourceController.php, the code comments are not consistent with the controller itself

PHP
<?php
 
namespace api\modules\v1\controllers;
 
/**
 * Menu controller for the `v1` module
 */
class ClientResourceController extends \api\controllers\ClientResourceController
{
    public $modelClass = 'api\modules\v1\models\Resource';
}

Adjust to:

PHP
<?php
 
namespace api\modules\v1\controllers;
 
/**
 * ClientResource controller for the `v1` module
 */
class ClientResourceController extends \api\controllers\ClientResourceController
{
    public $modelClass = 'api\modules\v1\models\Resource';
}

6. Directory: the method files in \api\rests\client_resource need to be renamed:

Rename \api\rests\client_resource\ResourceUpdateAction.php to: \api\rests\client_resource\MakeUpAction.php

7. Logged in, desktop, \api\config\urlManager.php, configuration: ‘controller’ => [‘v1/plan-task-resource’], a space is needed after the comma in the array

PHP

        // 任务管理 - 素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/plan-task-resource'],
            'only' => ['index','delete','create'],
            'tokens' => ['{id}' => ''],
            'extraPatterns' => [
                'POST resource' => 'create',
            ],
        ],

Adjust to:

PHP

        // 任务管理 - 素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/plan-task-resource'],
            'only' => ['index', 'delete', 'resource'],
            'tokens' => ['{id}' => ''],
            'extraPatterns' => [
                'POST resource' => 'resource',
            ],
        ],

8. Controller: \api\controllers\PlanTaskResourceController.php, the actions() method needs to be adjusted. yii\rest\ActiveController provides some default actions, and if they are not needed, they must be destroyed. When displaying data via RESTful APIs, it is often necessary to check whether the current user has permission to access and operate on the requested resource. In yii\rest\ActiveController, you can override the checkAccess() method to perform the permission check. Before and after =>, only a single space is needed; alignment is not required.

PHP

    /**
     * @inheritdoc
     */
    public function actions()
    {
        $actions = parent::actions();
        $actions['delete']['class'] = 'api\rests\plan_task_resource\DeleteAction';
        $actions['index']['class'] = 'api\rests\plan_task_resource\IndexAction';
        $actions['create'] = [
            'class'      => 'api\rests\plan_task_resource\ResourceAction',
            'modelClass' => $this->modelClass,
        ];
        return $actions;
    }

Adjust to:

PHP

    /**
     * @inheritdoc
     */
    public function actions()
    {
        $actions = parent::actions();
        // 禁用"view"、"create"、"update"、"options"动作
        unset($actions['view'], $actions['create'], $actions['update'], $actions['options']);
        $actions['delete']['class'] = 'api\rests\plan_task_resource\DeleteAction';
        $actions['index']['class'] = 'api\rests\plan_task_resource\IndexAction';
        $actions['resource'] = [
            'class' => 'api\rests\plan_task_resource\ResourceAction',
            'modelClass' => $this->modelClass,
			'checkAccess' => [$this, 'checkAccess'],
        ];
        return $actions;
    }

9. Controller in module v1: \api\modules\v1\controllers\ResourceController.php, the class name and file name are not consistent, and the code comments are not consistent with the controller itself. IDE prompt: non-controller class file, as shown in Figure 1

Rename \api\modules\v1\controllers\ResourceController.php to: \api\modules\v1\controllers\PlanTaskResourceController.php

IDE prompt: non-controller class file
Figure 1
PHP
<?php
 
namespace api\modules\v1\controllers;
 
/**
 * Menu controller for the `v1` module
 */
class PlanTaskResourceController extends \api\controllers\PlanTaskResourceController
{
    public $modelClass = 'api\modules\v1\models\Resource';
}

Adjust to:

PHP
<?php
 
namespace api\modules\v1\controllers;
 
/**
 * PlanTaskResource controller for the `v1` module
 */
class PlanTaskResourceController extends \api\controllers\PlanTaskResourceController
{
    public $modelClass = 'api\modules\v1\models\Resource';
}

10. Logged in, mobile, \api\config\urlManager.php, configuration: ‘controller’ => [‘v1/mobile/plan-task-resource’], a space is needed after the comma in the array, and the code comments are not consistent with the menu structure

PHP

        // 移动端 - 任务素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/mobile/plan-task-resource'],
            'only' => ['index','delete','create'],
            'tokens' => ['{id}' => ''],
            'extraPatterns' => [
                'POST resource' => 'create',
            ],
        ],

Adjust to:

PHP

        // 移动端 - 任务 - 素材
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => ['v1/mobile/plan-task-resource'],
            'only' => ['index', 'delete', 'resource'],
            'tokens' => ['{id}' => ''],
            'extraPatterns' => [
                'POST resource' => 'resource',
            ],
        ],

11. Controller: \api\controllers\mobile\PlanTaskResourceController.php, the actions() method needs to be adjusted. A blank line is needed between the actions() method and the public property $serializer

PHP
<?php
 
namespace api\controllers\mobile;
 
class PlanTaskResourceController extends \api\controllers\PlanTaskResourceController
{
    public $serializer = [
        'class' => 'api\rests\mobile\plan_task_resource\Serializer',
        'collectionEnvelope' => 'items',
    ];
    /**
     * @inheritdoc
     */
    public function actions()
    {
        $actions = parent::actions();
        $actions['delete']['class'] = 'api\rests\mobile\plan_task_resource\DeleteAction';
        $actions['index']['class'] = 'api\rests\mobile\plan_task_resource\IndexAction';
        $actions['create']['class'] = 'api\rests\mobile\plan_task_resource\ResourceAction';
        return $actions;
    }
}

Adjust to:

PHP
<?php
 
namespace api\controllers\mobile;
 
class PlanTaskResourceController extends \api\controllers\PlanTaskResourceController
{
    public $serializer = [
        'class' => 'api\rests\mobile\plan_task_resource\Serializer',
        'collectionEnvelope' => 'items',
    ];
 
    /**
     * @inheritdoc
     */
    public function actions()
    {
        $actions = parent::actions();
        $actions['delete']['class'] = 'api\rests\mobile\plan_task_resource\DeleteAction';
        $actions['index']['class'] = 'api\rests\mobile\plan_task_resource\IndexAction';
        $actions['resource']['class'] = 'api\rests\mobile\plan_task_resource\ResourceAction';
        return $actions;
    }
}

12. Controller: \api\controllers\mobile\ResourceController.php, needs to be deleted

13. Controller in module v1: \api\modules\v1\controllers\mobile\ResourceController.php, needs to be deleted

14. Directory: the method files in \api\rests\mobile\plan_task_resource need to be adjusted
\api\rests\mobile\plan_task_resource\Action.php

PHP
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
 
namespace api\rests\mobile\plan_task_resource;
 
 
/**
 * Action is the base class for action classes that implement RESTful API.
 *
 * For more details and usage information on Action, see the [guide article on rest controllers](guide:rest-controllers).
 *
 * @author Qiang Wang <shuijingwanwq@163.com>
 * @since 1.0
 */
class Action extends \api\rests\plan_task_resource\Action
{
 
}

\api\rests\mobile\plan_task_resource\Action.php
Adjust to:

PHP
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
 
namespace api\rests\mobile\plan_task_resource;
 
class Action extends \api\rests\plan_task_resource\Action
{
 
}

The following 3 files: \api\rests\mobile\plan_task_resource\DeleteAction.php, \api\rests\mobile\plan_task_resource\IndexAction.php, and \api\rests\mobile\plan_task_resource\Serializer.php, all need their corresponding comments deleted

\api\rests\mobile\plan_task_resource\ResourceAction.php

PHP
<?php
 
namespace api\rests\mobile\plan_task_resource;
 
use Yii;
use yii\db\ActiveRecord;
use yii\rest\Action;
use yii\web\ServerErrorHttpException;
use api\models\Resource;
use api\models\PlanTask;
 
class ResourceAction extends \api\rests\plan_task_resource\ResourceAction
{
 
}

\api\rests\mobile\plan_task_resource\ResourceAction.php, an unused file, its references need to be deleted, as shown in Figure 2

Unused file, its references need to be deleted
Figure 2

Adjust to:

PHP
<?php
 
namespace api\rests\mobile\plan_task_resource;
 
class ResourceAction extends \api\rests\plan_task_resource\ResourceAction
{
 
}

15. The routing design is problematic in a certain respect, as it does not fully utilize the default actions provided by yii\rest\ActiveController. However, since the API needs to be backward compatible, the routes are difficult to adjust and have to be kept as they are. In summary, I suggest that colleagues refer to the implementation of other features; if similar problems exist, they all need to be resolved one by one.

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系