在 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'],
    ];

基于 frontend 应用上的 Gii 生成模型,编辑/environments/dev/frontend/config/main-local.php

图1

4、在 Windows PowerShell 中执行 ./init,以覆盖/frontend/config/main-local.php,设置 Gii 允许访问的IP,如图2

在 Windows PowerShell 中执行 ./init,以覆盖/frontend/config/main-local.php,设置 Gii 允许访问的IP

图2

5、打开网址:http://www.kaiqiu_shujujiexi_api.dev/index.php?r=gii,可以访问 Gii 了,如图3

打开网址:http://www.kaiqiu_shujujiexi_api.dev/index.php?r=gii,可以访问 Gii 了

图3

6、编辑/frontend/config/main.php,以支持网址美化,如图4

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
编辑/frontend/config/main.php,以支持网址美化

图4

7、打开网址:http://www.kaiqiu_shujujiexi_api.dev/gii,如图5

打开网址:http://www.kaiqiu_shujujiexi_api.dev/gii

图5

8、基于数据库表kq_schedule建立相应模型,如图6

基于数据库表kq_schedule建立相应模型

图6

9、点击Model Generator下的Start按钮,生成模型Schedule,命名空间为common/models,以便于后期其他应用皆可以使用此模型,此时无需支持国际化,如图7

点击Model Generator下的Start按钮,生成模型Schedule,命名空间为common/models,以便于后期其他应用皆可以使用此模型,此时无需支持国际化

图7

10、点击 Generate 按钮,生成模型文件/common/models/Schedule.php,如图8

点击 Generate 按钮,生成模型文件/common/models/Schedule.php

图8

11、创建一个控制器/shujujiexi/controllers/ScheduleController.php,如图9

创建一个控制器/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

配置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

在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应

图11

14、为了在shujujiexi应用中实现自身的业务逻辑,建议新建/shujujiexi/models/Schedule.php,其继承至/common/models/Schedule,如图12

为了在shujujiexi应用中实现自身的业务逻辑,建议新建/shujujiexi/models/Schedule.php,其继承至/common/models/Schedule

图12

15、编辑控制器/shujujiexi/controllers/ScheduleController.php,重新指定模型为shujujiexi/models/Schedule,如图13

编辑控制器/shujujiexi/controllers/ScheduleController.php,重新指定模型为shujujiexi/models/Schedule

图13

16、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应,如图11

在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应

图11

17、在Postman中PUT:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules/1,正确响应,如图14

在Postman中PUT:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules/1,正确响应

图14

18、配置 only 和 except 选项来明确列出哪些行为支持, 哪些行为禁用。例如,只让其支持GET列表,则可以修改urlManager组件的配置,如图15

配置 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

在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

基于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

对于404响应格式为HTML的解决,编辑/shujujiexi/config/main.php,设置默认的响应格式为JSON

图18

 

        'response' => [
            'format' => yii/web/Response::FORMAT_JSON,
        ],

22、再次执行第19项,404响应,其格式为JSON,如图19

再次执行第19项,404响应,其格式为JSON

图19

23、数据序列化的实现,在响应主体内包含分页信息来 简化客户端的开发工作,编辑/shujujiexi/controllers/ScheduleController.php,如图20

数据序列化的实现,在响应主体内包含分页信息来 简化客户端的开发工作,编辑/shujujiexi/controllers/ScheduleController.php

图20

 

    public $serializer = [
        'class' => 'yii/rest/Serializer',
        'collectionEnvelope' => 'items',
    ];

24、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应,在响应主体内包含分页信息,如图21

在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,正确响应,在响应主体内包含分页信息

图21

25、RESTful APIs 通常是无状态的,因此,配置user 应用组件,编辑/shujujiexi/config/main.php,如图22

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

版本化的实现,新建目录/shujujiexi/modules

图23

27、/shujujiexi/modules/v1/Module.php,其内容,如图24

/shujujiexi/modules/v1/Module.php,其内容

图24

28、/shujujiexi/modules/v1/controllers/ScheduleController.php,其内容,如图25

/shujujiexi/modules/v1/controllers/ScheduleController.php,其内容

图25

29、/shujujiexi/modules/v1/models/Schedule.php,其内容,如图26

/shujujiexi/modules/v1/models/Schedule.php,其内容

图26

30、配置URL规则,修改urlManager组件的配置,如图27

配置URL规则,修改urlManager组件的配置

图27

31、配置模块规则,如图28

配置模块规则

图28

 

    'modules' => [
        'v1' => [
            'basePath' => '@app/modules/v1',
            'class' => 'shujujiexi/modules/v1/Module'
        ],
    ],

31、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,404响应,符合预期,如图29

在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/schedules,404响应,符合预期

图29

32、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules,正确响应,如图30

在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

复制/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

编辑控制器/shujujiexi/controllers/ScheduleController.php

图32

36、在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules,正确响应,如图33

在Postman中GET:shujujiexi.kaiqiu_shujujiexi_api.dev/v1/schedules,正确响应

图33

37、如何自由定义此请求的响应的实现流程,分析/vendor/yiisoft/yii2/rest/ActiveController.php可发现,Index操作默认实现类为yii/rest/IndexAction,如图34

如何自由定义此请求的响应的实现流程,分析/vendor/yiisoft/yii2/rest/ActiveController.php可发现,Index操作默认实现类为yii/rest/IndexAction

图34

38、复制/vendor/yiisoft/yii2/rest/IndexAction.php至/shujujiexi/rests/schedule/IndexAction.php,如图35

复制/vendor/yiisoft/yii2/rest/IndexAction.php至/shujujiexi/rests/schedule/IndexAction.php

图35

39、编辑控制器/shujujiexi/controllers/ScheduleController.php,如图36

编辑控制器/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

编辑/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

在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

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/180473.html

(0)
上一篇 2021年10月31日
下一篇 2021年10月31日

相关推荐

发表回复

登录后才能评论