Rajiv Pingale
Rajiv Pingale

Reputation: 1015

Yii URLpath Customization for REST API

I am working on YII (1.x) REST API. I want to update URL according to following format

 GET api/user =>  Should return list of User
 GET api/user/$id =>  Should return one USER with provided ID
 DELETE api/user/$id =>  Should delete respective user

I have added following code in my Main config file

array('api/list', 'pattern' => 'api/<model:\w+>', 'verb' => 'GET'), 
array('api/view', 'pattern' => 'api/<model:\w+>/<id:\d+>', 'verb' => 'GET'),
array('api/update', 'pattern' => 'api/<model:\w+>/<id:\d+>', 'verb' => 'PUT'),
array('api/delete', 'pattern' => 'api/<model:\w+>/<id:\d+>', 'verb' => 'DELETE'),

It is not working as expected, to get access to code I have to provide URL in following format

http://myServer/index.php/api/user/view/model/user/id/$USERID

Above URL return $_GET value as array("id"=>$USERID);

If I use following URL, (which I want to use)

http://myServer/index.php/api/user/$USERID

It returns $_GET value as NULL or sometime as array($USERID => NULL);

Please let me know the solution for same.

Upvotes: 1

Views: 241

Answers (2)

I have tested your rules with both Yii 1.1.10 and 1.1.14 and it did work on both versions.

This is the configuration used for the urlManager:

'urlManager'=>array(
    'urlFormat' => 'path',
    'showScriptName'=>true,
    'rules'=>array(
        array('api/list', 'pattern' => 'api/<model:\w+>', 'verb' => 'GET'), 
        array('api/view', 'pattern' => 'api/<model:\w+>/<id:\d+>', 'verb' => 'GET'),
        array('api/update', 'pattern' => 'api/<model:\w+>/<id:\d+>', 'verb' => 'PUT'),
        array('api/delete', 'pattern' => 'api/<model:\w+>/<id:\d+>', 'verb' => 'DELETE'),
    ),
)

You can see I had to set urlFormat to 'path', otherwise rules won't work as expected since you will not be passing parameters as query string.

And tested with the following urls:

/index.php/api/User
/index.php/api/User/123

And they work properly by pointing to list and view actions.

One last note:

You should also check you are not using any extension of CUrlManager that could modify the original rules from the configuration file.

In another project I was using MLUrlManager extension that was adding a prefix with the languages in front of every rule. In case you use that you should adjust the code to handle it differently depending if the rule is a string or a array.

Example:

$newRules = array();
foreach ($this->rules as $reg => $rule) {          
    if ($reg === 'robots.txt') {
      $newRules[$reg] = $rule;
    } elseif (is_string($rule)) {
      $newRules['<language:'.$langReg.'>/'.$reg] = $rule;
    } elseif (is_array($rule)) { // special handling for rules defined as array
      $rule['pattern']='<language:'.$langReg.'>/'.$rule['pattern'];
      $newRules[$reg] = $rule;
    }
}

Upvotes: 1

DiegoCoderPlus
DiegoCoderPlus

Reputation: 770

this is how we made it work:

'api/<controller:\w+>'=>array('<controller>/restList', 'verb'=>'GET'),
                                'api/<controller:\w+>/<id:\w*>'=>array('<controller>/restView', 'verb'=>'GET'),
                                'api/<controller:\w+>/<id:\w*>/<var:\w*>'=>array('<controller>/restView', 'verb'=>'GET'),
                                'api/<controller:\w+>/<id:\w*>/<var:\w*>/<var2:\w*>'=>array('<controller>/restView', 'verb'=>'GET'),

                                array('<controller>/restUpdate', 'pattern'=>'api/<controller:\w+>/<id:\w*>', 'verb'=>'PUT'),
                                array('<controller>/restUpdate', 'pattern'=>'api/<controller:\w+>/<id:\w*>/<var:\w*>', 'verb'=>'PUT'),
                                array('<controller>/restUpdate', 'pattern'=>'api/<controller:\w*>/<id:\w*>/<var:\w*>/<var2:\w*>', 'verb'=>'PUT'),

                                array('<controller>/restDelete', 'pattern'=>'api/<controller:\w+>/<id:\w*>', 'verb'=>'DELETE'),
                                array('<controller>/restDelete', 'pattern'=>'api/<controller:\w+>/<id:\w*>/<var:\w*>', 'verb'=>'DELETE'),
                                array('<controller>/restDelete', 'pattern'=>'api/<controller:\w+>/<id:\w*>/<var:\w*>/<var2:\w*>', 'verb'=>'DELETE'),

                                array('<controller>/restCreate', 'pattern'=>'api/<controller:\w+>', 'verb'=>'POST'),
                                array('<controller>/restCreate', 'pattern'=>'api/<controller:\w+>/<id:\w+>', 'verb'=>'POST'),

Upvotes: 0

Related Questions