Zend framework 使用Zend的Rest API的正确路由

Zend framework 使用Zend的Rest API的正确路由,zend-framework,rest,routing,Zend Framework,Rest,Routing,我正试图在我的网站上实现一个RESTAPI 我的问题是,默认的Zend路由会妨碍我。我第一次尝试使用Zend_Rest_路由,但我无法理解如何正确地将其用于“深度”路由,即网站/api/resource1/filter/resource2/id 使用默认的Zend路由,我需要创建一个巨大的Resource1控制器来处理所有可能的操作,我认为这不是一个“好”的方法 我尝试过使用Resauce()、创建api模块和添加路由,但无法使其正常工作: 我添加的模式是: $this->addR

我正试图在我的网站上实现一个RESTAPI

我的问题是,默认的Zend路由会妨碍我。我第一次尝试使用Zend_Rest_路由,但我无法理解如何正确地将其用于“深度”路由,即网站/api/resource1/filter/resource2/id

使用默认的Zend路由,我需要创建一个巨大的Resource1控制器来处理所有可能的操作,我认为这不是一个“好”的方法

我尝试过使用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/资源为我提供了 资源1控制器,好吗
  • 网站/api/resource/filter让我进入 资源1过滤控制器,好吗
  • website/api/resource/filter/:id获取 自定义控制器,好吗
  • 我想让website/api/resource/:id让我访问同一个自定义控制器。。。但它将我重定向到Resource1控制器
有什么解决方案可以让我正确地创建API?使用Zend_Rest_路线有没有一个好方法


编辑:迈克

我觉得我不适合使用不同的控制器,因为我需要路径“website/api/resource/:id”和“website/api/resource/filter/:id”来给出几乎完全相同的结果(唯一的区别是,因为过滤器在那里,我可能会在这里收到一条消息,告诉我“内容已过滤”)

我认为创建另一个几乎相同的控制器是一种浪费,而我本可以使用同一个控制器,只是检查参数“过滤器”是否存在


但是,我不想使用基本的Zend路由,因为对于路径“website/api/resource/filter/resource2”,我希望有一个完全不同的组件,所以我想使用另一个控制器,特别是因为我试图使用Zend_Rest_操作,并且需要我的控制器使用基本操作getAction()、putAction()、postAction()和deleteAction()。

好的,我没有得到好的控制器的原因是因为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'));

好的,我没有得到好的控制器的原因是因为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'));

请您解释一下为什么您需要两个指向同一控制器的URI模式。更好的解决方案可能是为两种模式中的每一种使用单独的控制器,并将任何共享逻辑移动到您的模型中

为每个路由模式强制一个唯一的控制器是一个有意的设计决策,所以我很想听到关于您的用例的更多细节,如果您觉得这不合适的话


我认为这是一种浪费 另一个几乎相同的控制器 当我可以用同样的 控制器,只需检查 存在参数“过滤器”

就我个人而言,我认为将共享逻辑移动到模型中并保持控制器的精简更为干净。对我来说,这不是浪费,只是更有组织性——随着时间的推移,它将使代码更易于管理

如果确实需要使用同一个控制器,则始终可以使用查询参数,这样就可以了:

api/resource/foo?filter=true
该URI将由第一个路由(api/resource/:id'=>'custom')免费处理


请考虑使用两个控制器,我认为这是一个更好的方法。

< P>请解释为什么你需要两个URI模式指向同一个控制器。更好的解决方案可能是为两种模式中的每一种使用单独的控制器,并将任何共享逻辑移动到您的模型中

为每个路由模式强制一个唯一的控制器是一个有意的设计决策,所以我很想听到关于您的用例的更多细节,如果您觉得这不合适的话


我认为这是一种浪费 另一个几乎相同的控制器 当我可以用同样的 控制器,只需检查 存在参数“过滤器”

就我个人而言,我认为将共享逻辑移动到模型中并保持控制器的精简更为干净。对我来说,这不是浪费,只是更有组织性——随着时间的推移,它将使代码更易于管理

如果确实需要使用同一个控制器,则始终可以使用查询参数,这样就可以了:

api/resource/foo?filter=true
该URI将由第一个路由(api/resource/:id'=>'custom')免费处理


请考虑使用两个控制器,我认为这是一个更好的方法。

谢谢你,迈克。我已经使用了过滤器参数,但我的一些控制器已经变得相当胖,使用单独的控制器可以避免使用非常大的switch语句。在考虑了很多之后,我想我会尝试使用,就像你建议的那样,毕竟,多个控制器,因为我认为当你谈论一个更容易管理的代码时,你有一个观点。非常感谢你提供的有用建议,我想我想尽量少复制代码,但如果我继续这样做的话,可能会让人很难理解。谢谢你,迈克。我已经使用了过滤器参数,但我的一些控制器已经变得相当胖,使用单独的控制器可以避免使用非常大的开关