0
votes

HI Im looking for some information on the best way to route requests to a custom module in the Yii framework.

I am implementing a RestFul Api for a project and was hoping that there was some way i could simply route all requests to api/ to the module where the rest api lives. Even better than that would be away to someone how route the api requests to a custom UrlManager class that extends CUrlManager in the module that then deals with the routes. so a request to mydomain/api/user/model would actually be deferred and handled by a UrlManager component in the module and other requests ie mydoamin.com/client/create would simply be handled by the normal yii applicaton. As far as i can tell this isnt possible!!

So i will settle for definig a url manager class in my config that catches the api routes like so

class UrlManager extends CUrlManager
{
    protected function processRules()
    {
        if(!isset($_GET['r']))
        {           
            $this->setUrlFormat('path');
            $this->showScriptName=false;
            $this->rules=array(

                //Api Rest Patterns
                array('api/list', 'pattern'=>'^api/user/<model:\w+>', 'verb'=>'GET'),
                array('api/view', 'pattern'=>'^api/user/<model:\w+>/<id:\d+>', 'verb'=>'GET'),
                array('api/update', 'pattern'=>'^api/user/<model:\w+>/<id:\d+>', 'verb'=>'PUT'),
                array('api/delete', 'pattern'=>'^api/user/<model:\w+>/<id:\d+>', 'verb'=>'DELETE'),
                array('api/add', 'pattern'=>'^api/user/<model:\w+>', 'verb'=>'POST'),
                array('api/test', 'pattern'=>'^api/user/test/<model:\w+>'),
                array('api/login', 'pattern'=>'^api/user/<model:\w+>/login'),
                array('api/logout', 'pattern'=>'^api/user/<model:\w+>/logout'),


                // Other controllers
                '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',                
                '<action:\w+>'=>'site/<action>',
            );
        }
        return parent::processRules();
    }
}

My question is then, how do i route the request to a Controller in the Module? ie module/RestApi/controller/UserApiController.php

array('ModuleController/action' , pattern=>'api/user/<model>' , 'verb'=>'GET)

I thought about this

'controllerMap' => array(
    'api'=>'application.modules.RestApi.components.ApiManager',
),

But im pretty certain i need two points of access, one for dealing with admin tasks on the api and one for users, so currently my controller structure looks like:

  • RestApiController
  • UserApiController (extends RestApiController)
  • AdminApiController (extends RestApiController)

So if there was a way to dynamically route the actions to the child controllers that might work? Hope i haven't been to confusing here really hope so of you Yii Masters can help with this problem!!

Thanks in advance

1

1 Answers

1
votes

I might have misunderstood your question (so correct me if I did), but can't you just use the normal urlmanager with 'normal' rules configured like so:

'rules' = array(
    //Api Rest Patterns
    array('restApi/userApi/list', 'pattern'=>'^api/user/<model:\w+>', 'verb'=>'GET'),
    array('restApi/userApi/view', 'pattern'=>'^api/user/<model:\w+>/<id:\d+>', 'verb'=>'GET'),
    array('restApi/userApi/update', 'pattern'=>'^api/user/<model:\w+>/<id:\d+>', 'verb'=>'PUT'),
    array('restApi/userApi/delete', 'pattern'=>'^api/user/<model:\w+>/<id:\d+>', 'verb'=>'DELETE'),
    array('restApi/userApi/add', 'pattern'=>'^api/user/<model:\w+>', 'verb'=>'POST'),
    array('restApi/userApi/test', 'pattern'=>'^api/user/test/<model:\w+>'),
    array('restApi/userApi/login', 'pattern'=>'^api/user/<model:\w+>/login'),
    array('restApi/userApi/logout', 'pattern'=>'^api/user/<model:\w+>/logout'),


    // Other controllers
    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',                
    '<action:\w+>'=>'site/<action>',
)

I'm pretty sure that something like this should work (not entirely sure about the camelCasing though). The route for a module action being '<moduleid>/<controllerid>/<actionid>', which I know for sure because I used it more than once.