user1066183
user1066183

Reputation: 2584

Zend_Rest_Route and hierarchical routes

Using Zend 1.9, I am trying to use Zend_Rest_Route to implement hierarchical url. So I have 2 restFul controller (users and items) and invoke the second controller using hierarchical routes.

Example: (consider GET http verb)

Example: (consider POST http verb)

Example: (consider PUT http verb)

Example: (consider DELETE http verb)

It seems Zend Framework don't provide this feature out of the box, so I have try to implement my custom solution but I am not very satisfied.

 $front = Zend_Controller_Front::getInstance();

 $restRoute = new Zend_Rest_Route($front, [], [
 'moduleName' => [
    'users'
    ]
 ]);
 $front->getRouter()->addRoute('users', $restRoute);   

$route = new Zend_Controller_Router_Route('moduleName/users/:user_id/items', [
    'controller' => 'items',
    'module' => 'moduleName',
    'action' => 'generic'
    ]);
$front->getRouter()->addRoute('items_generic', $route);

$route = new Zend_Controller_Router_Route('moduleName/users/:user_id/items/:item_id', [
    'controller' => 'items',
    'module' => 'moduleName',
    'action' => 'specific'
    ]);
$front->getRouter()->addRoute('items_specific', $route);

This is a prototipe of itemsController.php:

class ModuleName_ItemsController extends Zend_Controller_Action
{


  public function genericAction () //called from http://example.org/users/234/items
  {
    if ($this->getRequest()->isGet()) {
      $this->privateindex();
    } else if ($this->getRequest()->isPost()){
      $this->privatepost();
    }
  }

  public function specificAction () //called from http://example.org/users/234/items/34
  {
    if ($this->getRequest()->isGet()) {
      $this->privateshow();
    } else if ($this->getRequest()->isPut() ||$this->getRequest()->isPost()){
      $this->privateput();
    }else if($this->getRequest()->isDelete()){
      $this->privatedelete();
    }
  }


  private function privateindex(){ return $this->_helper->json->sendJson([
          'items' => 'indexPrivata'
      ]);}

  private function privatepost(){ return $this->_helper->json->sendJson([
      'items' => 'postPrivata'
      ]);}

  private function privateshow(){ return $this->_helper->json->sendJson([
      'items' => 'showPrivata'
      ]);}

  private function privateput(){ return $this->_helper->json->sendJson([
      'items' => 'putPrivata'
      ]);}

  private function privatedelete(){ return $this->_helper->json->sendJson([
      'items' => 'deletePrivata'
      ]);}
}

This solution seems work but in my opinion is not the best way to do this.

There is a better solution to implement hierarchical restFul routes in Zend?

Upvotes: 2

Views: 197

Answers (1)

doydoy44
doydoy44

Reputation: 5782

You can manage route with a plugin.

For example, you can try something like this (not tested with ZF 1.9):

In your bootstrap, add this function (to declare the plugin)

public function _initPlugins(){
    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin(new Application_Plugin_PRoutage());
}

with this example, the application/plugins folder, create the PRoutage.php plugin like this:

class Application_Plugin_PRoutage extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {   
        if (preg_match('/(users)(.*)(items)/', $request->getPathInfo())){

            $request->setControllerName('items'); // itemsController

            if ($request->isGet()){
                if (preg_match('/(users\/)(.*)(items\/)([0-9].)/', $request->getPathInfo())){
                    // http://example.org/users/234/items/34 //this point to showAction of itemsController
                    $request->setActionName('show');
                }
                else{
                    // http://example.org/users/234/items //this point to indexAction of itemsController
                    $request->setActionName('index');
                }
            } elseif ($request->isPost()){
                // http://example.org/users/234/items //this point to postAction of itemsController
                $request->setActionName('post');
            } elseif ($request->isPut()){
                // http://example.org/users/234/items/34 //this point to putAction of itemsController
                $request->setActionName('put');
            }elseif ($request->isDelete()){
                // http://example.org/users/234/items/34 //this point to deleteAction of itemsController
                $request->setActionName('delete');
            }
            $request->setDispatched(true) ;
        }
        elseif (preg_match('/(users)/', $request->getPathInfo())){

            $request->setControllerName('users'); // usersController

            if ($request->isGet()){
                if (preg_match('/(users\/)([0-9].)/', $request->getPathInfo())){
                    // http://example.org/users/234 //this point to getAction of usersController 
                    $request->setActionName('get');
                }
                else{
                    // http://example.org/users/ //this point to indexAction of usersController
                    $request->setActionName('index');
                }
            } elseif ($request->isPost()){
                // http://example.org/users/ //this point to postAction of usersController
                $request->setActionName('post');
            } elseif ($request->isPut()){
                // http://example.org/users/234 //this point to putAction of usersController
                $request->setActionName('put');
            }elseif ($request->isDelete()){
                // http://example.org/users/234 //this point to deleteAction of usersController
                $request->setActionName('delete');
            }
            $request->setDispatched(true) ;
        }
    }      

}

Of course, you can improve it.

I hope it will help you.

Upvotes: 2

Related Questions