Как настроить иерархические Zend Rest Routes?

В Zend Framework я пытаюсь построить маршруты для REST API на ресурсах, организованных по следующей схеме:

Как мне установить это с Zend_Rest_Route?

Вот как я настроил маршрут для ресурса users (users/:id) в моем файле bootstrap.php:

  $this->bootstrap('frontController');
  $frontController = Zend_Controller_Front::getInstance();
  $restRoute = new Zend_Rest_Route($frontController);
  $frontController->getRouter()->addRoute('default', $restRoute);

[Насколько я понимаю, это обход всех маршрутов, поэтому пользователи /324/items/34 приводят к параметрам, установленным как id=324 и items=34, и все будет отображаться в модели Users (передний модуль). Оттуда, я думаю, я мог бы просто проверить параметр items и получить элемент #34 для пользователя #324 по запросу get.]<=== Я только что проверил его, и, похоже, он не работает так:

Acessing / users / 234 / items / 43 и

var_dump($this->_getAllParams());

в действии get контроллера rest выдает следующий вывод:

array(4) {
 ["controller"]=> string(5) "users"
 ["action"]=>  string(3) "get"
 [2]=>  string(5) "items"  ["module"]=>  string(7) "default"]
}

Как-то оба идентификатора потерялись...

Кто-нибудь?

3 ответа

Решение

AFAIK, в Zend_Rest_Route нет функции, которая позволяла бы вам делать что-то подобное. Есть предложение, но не уверен, когда оно будет реализовано. Вы можете добавить это в Bootstrap, чтобы настроить этот собственный маршрут.

$front = $this->getResource('FrontController'); 
$testRoute = new Zend_Controller_Router_Route(
    'users/:user_id/items/:item_id',
    array(
        'controller' => 'users',
        'action' => 'item',
        'module' => 'default'
    )
);

$front->getRouter()->addRoute('test', $testRoute);

user_id или item_id становятся доступными в itemAction в UsersController в качестве параметров:

$user_id = $this->_request->getParam('user_id');

Я открываю исходный код решения в github и как пакет для композитора. см. https://github.com/aporat/Application_Rest_Controller_Route.

Я добавил новый класс, который расширяет Zend_Controller_Router_Route и добавляет возможность добавлять собственные маршруты отдыха, такие как

$frontController = Zend_Controller_Front::getInstance();
$frontController->getRouter()->addRoute('users-messages', new Application_Rest_Controller_Route($frontController, 'users/:user_id/messages', ['controller' => 'users-messages']));

Zend_Rest_Route отображает первый параметр после имени контроллера на 'id', только когда есть 1 параметр.

Лучшее решение, которое я придумал, это создать подкласс Zend_Rest_Route и переопределить функцию match(). Скопируйте функцию соответствия Zend_Rest_Route, но добавьте следующее непосредственно перед комментарием "Digest URI Params" (около 60 строк в).

if($pathElementCount > 1 && $path[0] != 'id') {
    $params['id'] = urldecode($path[0]);
    array_shift($path);
}  

Это должно дать вам функциональность, которую вы ищете.

Другие вопросы по тегам