Reputation: 2584
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)
indexAction
of usersController
getAction
of usersController
indexAction
of itemsController
showAction
of itemsController
Example: (consider POST http verb)
postAction
of usersController
postAction
of itemsController
Example: (consider PUT http verb)
putAction
of usersController
putAction
of itemsController
Example: (consider DELETE http verb)
deleteAction
of usersController
deleteAction
of itemsController
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
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