我正在尝试在我的网站上实现REST API。
我的问题是默认的Zend路由阻碍了。我第一次尝试使用Zend_Rest_Route,但我无法理解我应该如何正确地使用它来进行“深度”路由,即网站/ api / resource1 / filter / resource2 / id。
使用默认的Zend路由,我需要创建一个巨大的Resource1Controller来处理所有可能的操作,我认为这不是“好”的方法。
我尝试过使用Resauce(http://github.com/mikekelly/Resauce/),创建api模块并添加路由,但我无法正常工作:
我添加的模式是:
$this->addResauceRoutes(array(
'api/resource' => 'resource',
'api/resource/:id' => 'custom',
'api/resource/filter' => 'resource-filter',
'api/resource/filter/:id' => 'custom',
));
然后导致这个:
public function addResauceRoutes($routes) {
$router = Zend_Controller_Front::getInstance()->getRouter();
foreach ($routes as $pattern => $controller) {
$router->addRoute($controller,
new Zend_Controller_Router_Route($pattern, array(
'module' => 'api',
'controller' => $controller
)
)
);
}
Zend_Controller_Front::getInstance()->setRouter($router);
我有什么解决方案可以正确创建我的API?使用Zend_Rest_Route有一个很好的方法吗?
我觉得使用不同的控制器是不合适的,因为我需要使用“website / api / resource /:id”和“website / api / resource / filter /:id”来给我几乎完全准确的信息。相同的结果(唯一的区别是,因为过滤器在那里,我可能会收到一条消息告诉“内容过滤”这里)。
当我可以使用相同的控制器并检查是否存在参数“过滤器”时,我认为创建另一个几乎相同的控制器是浪费。
但是,我不想使用基本的Zend路由,因为路径“website / api / resource / filter / resource2”我想要一个完全不同的路由,所以我想使用另一个控制器,特别是因为我正在尝试使用Zend_Rest_Action并需要我的控制器使用基本动作getAction(),putAction(),postAction()和deleteAction()。
答案 0 :(得分:1)
请你能解释为什么你需要两个指向同一个控制器的URI模式。更好的解决方案可能是为两种模式中的每一种使用单独的控制器,并将任何共享逻辑移动到模型中。
为每个路由模式强制使用一个独特的控制器是一个有意的设计决策,因此我有兴趣听到有关您认为不合适的用例的更多详细信息。
我认为这是一种浪费 另一个几乎相同的控制 当我可以使用相同的 控制器,只是检查一个 参数“过滤器”存在。
就我个人而言,我认为将共享逻辑移入模型并保持控制器变得更加干净是更清晰的。对我来说,这不是浪费,而是更有条理 - 它将使您的代码更容易管理。
如果你真的需要使用相同的控制器,你总是可以使用查询参数,这样可以正常工作:
api/resource/foo?filter=true
该URI将由第一条路径('api / resource /:id'=>'custom')免费处理。
但请考虑使用两个控制器,我认为这是一种更好的方法。
答案 1 :(得分:0)
好吧,我没有得到好控制器的原因是因为Resauce使用控制器名称作为路由的名称,这必须是唯一的 - 所以指向“自定义”控制器的第二个url无法工作。现在我能够得到我想要的文件:)
因此,我直接使用$ router-> addRoute();而不是之前提到的。并且每次都定义新名称,即使指向同一个控制器。
示例:
$router->addRoute('resource', new Zend_Controller_Router_Route('/api/resources/:id', array('module' => 'api', 'controller' => 'resource')));
$router->addRoute('resourceFiltered', new Zend_Controller_Router_Route('/api/resources/filter1/:id', array('module' => 'api', 'controller' => 'resource', 'filter' => 'filter1'));