使用Zend正确路由Rest API

时间:2010-03-01 10:36:54

标签: zend-framework rest routing

我正在尝试在我的网站上实现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);
  • website / api / resource让我了 Resource1Controller,好的
  • website / api / resource / filter让我去了 resource1filterController,好的
  • website / api / resource / filter /:id让我来 自定义控制器,确定
  • 我想网站/ api / resource /:id让我进入同一个自定义控制器......但它将我重定向到Resource1Controller。

我有什么解决方案可以正确创建我的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()。

2 个答案:

答案 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'));