Yii2 using yii \ rest \ UrlRule with multiple parameters
I am trying to use Yii 2 routing for REST API.
Following the guide at http://www.yiiframework.com/doc-2.0/guide-rest-routing.html I have already defined (with success) many rules for the API entry point as follows:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user'
],
],
]
This rule defines:
- GET / users (list of users)
- GET / users / 123 (show detailed information of user 123)
My users now have games. So I would like to have urls:
- GET / users / 123 / games (list of games for user 123)
- GET / users / 123 / games / 864 (details of game 864 for user 123 - for example, his ratings)
I tried to define my new entry point (no success):
'rules' => [
... previous rules ...,
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'game'
],
'tokens' => [
'{userid}' => '<userid:\\d>',
'{gameid}' => '<gameid:\\d>',
],
'patterns' => [
'GET,HEAD /users/{userid}/games' => 'index',
'GET,HEAD /users/{userid}/games/{gameid}' => 'view',
]
]
]
This definition seems to be wrong because I am getting a 404 page not found error. How do I define new URL routes? I would like to use an equivalent format for my definitions by extending 'yii \ rest \ UrlRule'
I'm not sure if this is possible, the manual does not mention this case.
source to share
So I figured out how to use more complex rules.
First, the solution, then the explanation.
Here's the solution:
'rules' => [
... previous rules ...,
[
'class' => 'yii\rest\UrlRule',
'controller' => 'game',
'prefix' => '/users/<userid:\\d+>',
'tokens' => [
'{gameid}' => '<gameid:\\d+>',
],
'patterns' => [
'GET,HEAD' => 'index',
'GET,HEAD {gameid}' => 'view',
]
]
]
And now the explanation:
- At first, my userid / gameid attributes were poorly defined. No "+" after "\ d"
- The controller is automatically added as a prefix for templates. So you have to define both the controller and the prefix (which will be added before the controller).
- The parameters in the prefix don't seem to be parsed to find markers. So I wrote a direct expression in the prefix instead of adding "userid" as the token.
- Finally, when concatenating "prefix / controller / pattern" different "/" are automatically added, so you don't need to write them.
-
Don't forget the pluralization rule too! "game is" unique "but valid urls will be
- / users / 123 / games
- / users / 123 / games / 789
Hope this helps.
source to share
Just use yii2-nested-rest
It provides a REST API for MANY-to-MANY relationships in the Yii2 framework.
Hope's comments will make the magic clearer:
'rules' => [
// this usual rule for base Yii2 rest usage
['class' => 'yii\rest\UrlRule', 'controller' => ['sitecomponent' ,'sitepage' , 'sitedomain'], 'pluralize'=>false
],
// then rules for yii2-nested-rest
[
// url sitepage/NNN/sitecomponent[/MMM]
// ^^^^^^^^^ ^^^^^^^^^^^^
// resourceName model-endpoint
'class' => 'tunecino\nestedrest\UrlRule',
'modelClass' => 'app\models\SitePage',
'resourceName' => 'sitepage',
'relations' => ['components' => ['sitecomponent'=>'sitecomponent'] ],
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^
// relation name url-endpoint controller]
// defined in model SitePage model-endpoint with Actions from nested
],
[
// cross url sitecomponent/NNN/sitepage[/MMM]
'class' => 'tunecino\nestedrest\UrlRule',
'modelClass' => 'app\models\SiteComponent',
'resourceName' => 'sitecomponent',
'relations' => ['pages' => ['sitepage' => 'sitepage'] ],
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^
// relation name url-endpoint controller
// from model SiteComponent model-endpoint with Actions from nested
],
],
source to share