grigor/yii2-rest

完整REST

安装: 19

依赖: 1

建议者: 0

安全性: 0

星标: 0

关注者: 1

分支: 0

开放问题: 0

类型:yii2-extension

1.0.2 2021-05-21 21:25 UTC

This package is not auto-updated.

Last update: 2024-09-21 13:02:28 UTC


README

处理RESTful。允许任何类用作action。

建议与基于注解的yii2-generator配置生成器一起使用。

安装

安装此扩展的首选方法是通过composer

运行命令

php composer require --prefer-dist grigor/yii2-rest "1.0.1"

或添加到composer.json

"grigor/yii2-rest": "^1.0.1",

考虑系统中存在yii2-generator的配置

将文件夹frontend或backend复制到项目根目录,并根据您的喜好重命名,例如我将它命名为api。同时,不要忘记在文件common/config/bootstrap.php中添加以下行:Yii::setAlias('@api', dirname(dirname(DIR)) . '/api');

common/config/params.php文件可能如下所示

<?php
return [
    ...
    /**
     * Это пути где будут лежать настройки правил для рест апи и настройки методов которые будут отрабатывать в место actions.
     *
     * Если использовать yii2-generator, то лучше пути сразу писать без @alias или конвертировать
     * в относительный|реальный путь. Ниже будет описано почему или см. yii2-generator 
     * grigor\generator\tools\DeveloperTool::beforeAppRunScanDevDirectories($config);.
     */
    'serviceDirectoryPath' => Yii::getAlias('@api/data/static/services'),// тут будут лежать настройки методов.
    'rulesPath' => Yii::getAlias('@api/data/static/rules.php'), // тут сами правила со ссылками на настройки выше.
    /**
     * Параметр говорит генератору в каких папках ведется разработка ядра для апи, в общем случае где искать php файлы 
     * с аннотациями содержащими настройки для апи.
     * Этот параметр использует только yii2-generator, но он использует и параметры выше.
     */
    'devDirectories' => [
        Yii::getAlias('@api'),
    ]
    ...
];

console/config/main.php文件可能如下所示

...
    'bootstrap' => ['log', grigor\generator\GeneratorBootstrap::class],
    'modules' => [
        'generator' => [
            'class' => grigor\generator\Module::class,
        ],
    ],
...

api/config/main.php文件可能如下所示

<?php

$params = array_merge(
    require __DIR__ . '/../../common/config/params.php',
    require __DIR__ . '/../../common/config/params-local.php',
    require __DIR__ . '/params.php',
    require __DIR__ . '/params-local.php'
);

return [
    'id' => 'app-api',
    'basePath' => dirname(__DIR__),
    'bootstrap' => [
        'log',
        grigor\rest\RestBootstrap::class,
        [
            'class' => 'yii\filters\ContentNegotiator',
            'formats' => [
                'application/json' => 'json',
                'application/xml' => 'xml',
            ],
        ],
    ],
    'modules' => [
        'rest' => [
            'class' => grigor\rest\Module::class,
        ],
    ],
    'controllerNamespace' => 'api\controllers',
    'components' => [
        'request' => [
            'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ],
            'enableCsrfCookie' => false
        ],
        'response' => [
            'formatters' => [
                'json' => [
                    'class' => 'yii\web\JsonResponseFormatter',
                    'prettyPrint' => YII_DEBUG,
                    'encodeOptions' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
                ],
            ],
        ],
        'user' => [
            'identityClass' => 'common\models\User',
            'enableAutoLogin' => false,
            'enableSession' => false,
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'serviceInstaller' => [
            'class' => grigor\rest\urls\installer\ServiceInstaller::class,
            'whiteList' => false,
        ],
        'serviceMetaDataReader' => [
            'class' => grigor\rest\urls\installer\PhpServiceMetaDataReader::class,
            'serviceDirectoryPath' => $params['serviceDirectoryPath'],//берется из common/config/params.php
            'rulesPath' => $params['rulesPath'],//берется из common/config/params.php
        ],
        'urlManager' => [
            'class' => grigor\rest\urls\UrlManager::class,
            'enablePrettyUrl' => true,
            'enableStrictParsing' => true,
            'showScriptName' => false,
            'rules' => [
                'GET ' => 'site/index',
                'GET v1/shop' => 'site/index',
            ],
        ],
    ],
    'params' => $params,
];

参数

'rulesPath' => $params['rulesPath'],指向路由规则的文件,其外观大致如下

<?php

return [
    0 => [
        'pattern' => "v1/shop/products/<id:[\w\-]+>", // url по правилам Yii2 за исключением <controller...> (потом будет кидать исключение на такую настройку)
        'verb' => ['GET'], //метод по которому сее деяние будет доступно
        'alias' => 'product/index', // т.к. контроллеров при таком подходе нет, а для генерации url требуется роут, то прописываем любой не существующий
        'class' => 'grigor\rest\urls\ServiceRule', //правило (наследник UrlRule)
        'identityService' => 'eca98246-8562-4edb-8d5d-07c65558d9da' //идентификатор настройки для данного роута
    ],
    ... и еще куча правил
];

参数

'serviceDirectoryPath' => $params['serviceDirectoryPath'],指向包含action配置(可以是任何类)的文件夹。配置可以位于数据库或文件中,取决于ServiceMetaDataReaderInterface的实现。示例配置(一个配置一个文件),如果计划存储在文件中,则名称可以是这样的 eca98246-8562-4edb-8d5d-07c65558d9da.php 或任何其他名称。

<?php
return [
   /** могут использоваться для формирования белых списков уникальных для конкретно этого action */
    //  'permissions' => ["guest", "ruleName1", "ruleName2"],
    'service' => [
        'class' => 'api\project\SomeClass', //экземпляр класса который будет отрабатывать
        'method' => 'func' //метод который будет отрабатывать 
    ],
    'serializer' => 'api\serialize\SerializeProduct',
    'context' => 'api\context\FindModel', // ограничитель области действия - можно так сказать, (типа как findModel)
    /** если action предполагает просто какое то действие и после выполнения должен вернуть какой нибудь статус. */
   // 'response' => 201,
];

参数(非必需)- 'serializer' => 'api\serialize\SerializeProduct',

如果不希望处理fields()和extraFields(),可以使用自定义序列化器。它必须有一个必需的方法__invoke(...);这样就可以序列化单个实体,也可以序列化整个DataProviderInterface。

 public function __invoke(Product $product): array
    {
        return [
            'id' => $product->id,
            'name' => $product->name,
        ];
    }

参数(非必需)- 'context' => 'api\context\FindModel',限制条件可能如下

class FindModel implements ActionContextInterface
{

    public function getParams($args): ?array
    {
        $id = $args['key'];
        if ($id !== '...') {
            throw new NotFoundHttpException('Page not found.');
        }
        return ['id' => $id];
    }
}

它可以返回一个包含在执行方法中缺少的参数的数组。例如,我们有一个public function getProfile(string $id)方法,而api接口应该返回当前用户的配置文件。也就是说,对于系统用户,没有id参数,得到的URL大约是这样的 /v2/user/profile 方法 GET,一切正常,但我们使用public function getProfile(string $id)在这里需要传递user的id,在这种情况下是当前用户。

class FindModel implements ActionContextInterface
{

    public function getParams($args): ?array
    {
        return ['id' =>  \Yii::$app->user->id];// id тут сопоставится с параметром метода getProfile(string $id), потому называться должен также
        //причем, если в url будет добавлен параметр id как то так  /v2/user/profile/какойтоid (404) или /v2/user/profile?id=какойтоid (проигнорирован)  - он будет проигнорирован
    }
}

对于这些事情,服务和存储库非常适合。如果使用yii2-generator,则可以使用注解作为配置文件的替代品。基于注解生成配置和规则,可以写入文件或数据库(实现接口ServiceMetaDataReaderInterface以从数据库获取配置),这取决于个人喜好,在后一种情况下可以轻松组织管理自己的API的仪表板。这些系统被分开,因为在大多数情况下,在产品环境中不需要yii2-generator,但在开发系统中它非常方便,因为它不会影响应用程序的功能。

有关如何使用yii2-generator的更多信息,请参阅其页面

在example文件夹中,您可以在zip存档中找到文件示例。不要忘记namespace,它们可能不同。

测试

composer tests