grigor / yii2-rest
完整REST
Requires
- php: >=7.1
- yiisoft/yii2: ~2.0.0
- yiisoft/yii2-bootstrap: ~2.0.0
Requires (Dev)
- phpunit/phpunit: 8.5.x-dev
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