使用带有几个参数的yii \ rest \ UrlRule的Yii2路由

时间:2015-05-21 15:59:03

标签: php rest yii routing yii2

我正在尝试将Yii 2路由用于REST API。

http://www.yiiframework.com/doc-2.0/guide-rest-routing.html的教程之后,我已经为API入口点定义了很多规则(成功):

'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
        [
            'class' => 'yii\rest\UrlRule', 
            'controller' => 'user'
        ],
    ],
]

这样的规则定义:

  • GET / users(列出用户)
  • GET / users / 123(显示用户123的详细信息)

现在,我的用户有游戏。所以我想要网址:

  • GET / users / 123 / games(列出用户123的游戏)
  • GET / users / 123 / games / 864(用户123的游戏864的详细信息 - 例如他的分数)

我尝试定义我的新入口点(但没有成功),如下所示:

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

这个定义似乎错了,因为我收到了404 Page not found错误。 我该如何定义新的url路由? 我想为我的定义使用等效格式,扩展'yii \ rest \ UrlRule'

我不确定这是否可能,教程没有提到这个案例。

4 个答案:

答案 0 :(得分:4)

所以我想出了如何使用更复杂的规则。

首先是解决方案,然后是解释。

以下是解决方案:

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

现在的解释是:

  • 首先我的userid / gameid属性定义不明确。 “\ d”
  • 之后缺少“+”
  • 控制器似乎会自动添加为模式的前缀。因此,您必须定义控制器和前缀(将在控制器之前添加)。
  • 前缀中的参数似乎未被解析以查找令牌。所以我直接在前缀中写了正则表达式,而不是添加“userid”作为标记。
  • 最后,在连接“前缀/控制器/模式”时会自动添加各种“/”,因此您不必编写一个./ / li>
  • 也不要忘记复数规则! “游戏”是单数的“但有效的网址将是

    • /用户/ 123 /游戏
    • /用户/ 123 /游戏/ 789

希望它会有所帮助。

答案 1 :(得分:2)

我认为有一个简单的解决方案,请试试这个:

'rules' => [
                ...
                '/users/<userId:\\d+>/games' => 'game/index' ,
                '/users/<userId:\\d+>/games/<gameId:\\d+>' => 'game/view' ,
                ....
];

答案 2 :(得分:0)

只需使用yii2-nested-rest

即可

它为Yii2框架中的MANY到MANY关系提供REST API。

希望评论会让魔术变得更容易理解:

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

],

答案 3 :(得分:0)

获取xx.com/v2/publication/12/p/34

[
                'class' => 'yii\rest\UrlRule',
                'pluralize' => false,//controller是否复数
                'controller' => 'v2/publication',//此处一定要加上v2
                'tokens' => [
                    '{id}' => '<id:\\d[\\d,]*>',
                    '{phase}' => '<phase:\\d[\\d,]*>',
                ],
                // 通过extraPatterns和tokens来实现多个参数传递
                'extraPatterns' => [
                    'GET,HEAD {id}/p/{phase}' => 'phase',
                ],
            ],

行动中

public function actionPhase($id, $phase){}