мне нужен твой совет.
Мне нужно создать несколько действий в стиле RPC API-контроллера, сгенерированного Apigility.
Как мне сделать маршрутизацию, чтобы она работала, как в обычном приложении Zend.
'application' => array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',/*I need flexible route like this one*/
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
Код, сгенерированный Apigility:
<?php
namespace TestAPI\V1\Rpc\Test;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\JsonModel;
class TestController extends AbstractActionController
{
public function TestAction()
{
/*Added by myself*/
return new JsonModel(array(
'id' => 'test',
));
}
}
и маршрутизация генерируется следующим образом:
'controllers' => array(
'factories' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\TestControllerFactory',
),
),
'zf-rpc' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => array(
'service_name' => 'test',
'http_methods' => array(
0 => 'GET',
),
'route_name' => 'test-api.rpc.test',
),
),
Спасибо за помощь!
Мэттью Вейер О’Финни (создатель Apigility) не одобряет множественные действия на контроллер:
Нет.
Функциональность RPC Apigility устанавливает один маршрут -> один контроллер ->
одно действие (хотя мы допускаем несколько HTTP-методов к нему). Это
по нескольким причинам:
- Упрощает настройку
- Упрощает поиск кода для заданного маршрута (только одно место для поиска)
- Помогает предотвратить большие контроллеры
Что бы я сделал, это создать объект службы, который может обрабатывать различные
связанные операции, а затем обслуживание RPC для отдельной операции
(если эта операция не может быть описана с использованием различных HTTP-глаголов
по тому же маршруту, что есть). Затем введите каждый контроллер с этим
обслужить объект и вызвать соответствующий метод.
источник: https://groups.google.com/a/zend.com/d/msg/apigility-users/Or3xBLAd9Y0/RzQKIMpaV0cJ
Решение 1
Попробуйте зарегистрировать псевдонимы на ключе контроллера на вашем контроллере и зарегистрируйте каждый псевдоним в конфигурации zf-rpc.
Что-то вроде того:
'controllers' => array(
'factories' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\TestControllerFactory',
),
'aliases' => array(
'TestAPI\\V1\\Rpc\\Test2\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\Controller',
'TestAPI\\V1\\Rpc\\Test3\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\Controller',
),
),'zf-rpc' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => array(
'service_name' => 'test',
'http_methods' => array(
0 => 'GET',
),
'route_name' => 'test-api.rpc.test',
),
'TestAPI\\V1\\Rpc\\Test2\\Controller' => array(
'service_name' => 'test2',
'http_methods' => array(
0 => 'GET',
),
'route_name' => 'test-api.rpc.test2',
),
'TestAPI\\V1\\Rpc\\Test3\\Controller' => array(
'service_name' => 'test3',
'http_methods' => array(
0 => 'GET',
),
'route_name' => 'test-api.rpc.test3',
),
),
Возможно, вам придется скопировать и изменить конфигурацию de route и другие настройки.
Решение 2
Вы можете попробовать сгенерировать другой сервис rpc и изменить фабрику на псевдоним, все конфиги сгенерируют для вас.
после создания сервиса вы получите что-то вроде этого:
'controllers' => array(
'factories' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\TestControllerFactory',
'TestAPI\\V1\\Rpc\\Test2\\Controller' => 'TestAPI\\V1\\Rpc\\Test2\\TestControllerFactory',
),
),
Вы должны изменить что-то вроде этого:
'controllers' => array(
'factories' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\TestControllerFactory',
),
'aliases' => array(
'TestAPI\\V1\\Rpc\\Test2\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\Controller',
),
),
Вы можете попробовать это для маршрутизации:
'controllers' => array(
'factories' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => 'TestAPI\\V1\\Rpc\\Test\\TestControllerFactory',
),
),
'zf-rpc' => array(
'TestAPI\\V1\\Rpc\\Test\\Controller' => array(
'service_name' => 'test',
'http_methods' => array(
0 => 'GET',
),
'route_name' => 'test-api.rpc.test',
),
),
'router' => array(
'routes' => array(
'test-api.rpc.test' => array(
'type' => 'Segment',
'options' => array(
'route' => '/api/test[/:action_name]',
'defaults' => array(
'controller' =>'TestAPI\\V1\\Rpc\\Test\\Controller',
'action' => 'test',
),
),
),))
`
И в вашем контроллере:
<?php
namespace TestAPI\V1\Rpc\Test;
use Zend\Mvc\Controller\AbstractActionController;
class TestController extends AbstractActionController
{
public function testAction()
{
$action_name = $this->getEvent()->getRouteMatch()->getParam('action_name');
switch ($action_name) {
case 'test1':
return $this->test1Action();
default:
return array();
}
}
public function test1Action(){
//Your code here
return ...; //preferable to be array
}
}
URL-адрес … / api / test / test1
Я надеюсь, что это поможет вам.