Search code examples
phpzend-frameworkzend-framework2zend-framework-routing

ZF2 Route based on method while extending AbstractRestfulController


In Zend Framework 2 I am trying to route a few dynamic urls to specified actions in a controller that extends AbstractRestfulController, based on the request type. Problem is, the AbstractRestfulController keeps overriding these routes to the default actions get(), getList(), etc.

My routes are:

GET /my-endpoint/{other_id} - allAction()
POST /my-endpoint/{other_id} - createAction()
GET /my-endpoint/{other_id}/{id} - getAction()
PUT /my-endpoint/{other_id}/{id} - updateAction()
DELETE /my-endpoint/{other_id}/{id} - deleteAction()

My router config is:

'my-endpoint' => [
    'type' => 'segment',
    'options' => [
        'route' => 'my-endpoint/:other_id',
        'constraints' => [
            'other_id' => '[0-9]+',
        ],
        'defaults' => [
            'controller' => 'my-endpoint',
        ],
    ],
    'may_terminate' => true,
    'child_routes' => [
        'get' => [
            'type' => 'method',
            'options' => [
                'verb' => 'get',
                'defaults' => [
                    'action' => 'all',
                ],
            ],
        ],
        'post' => [
            'type' => 'method',
            'options' => [
                'verb' => 'post',
                'defaults' => [
                    'action' => 'create',
                ],
            ],
        ],
        'single' => [
            'type' => 'segment',
            'options' => [
                'route' => '[/:id]',
                'constraints' => [
                    'id' => '[0-9]+',
                ],
            ],
            'may_terminate' => true,
            'child_routes' => [
                'get' => [
                    'type' => 'method',
                    'options' => [
                        'verb' => 'get',
                        'defaults' => [
                            'action' => 'get',
                        ],
                    ],
                ],
                'update' => [
                    'type' => 'method',
                    'options' => [
                        'verb' => 'put',
                        'defaults' => [
                            'action' => 'update',
                        ],
                    ],
                ],
                'delete' => [
                    'type' => 'method',
                    'options' => [
                        'verb' => 'delete',
                        'defaults' => [
                            'action' => 'delete',
                        ],
                    ],
                ],
            ],
        ],
    ],
],

And my controller has the following actions:

public function allAction() {
    die('allAction');
}

public function createAction() {
    die('createAction');
}

public function getAction() {
    die('getAction');
}

public function updateAction() {
    die('updateAction');
}

public function deleteAction() {
    die('deleteAction');
}

How can I route specifically this way, so that no other request types are allowed to this controller / overriding the default AbstractRestfulController routes?

Also, I would like to continue extending this controller because I am actually extending a more generic controller which extends this Zend one.


Solution

  • Try to set: 'may_terminate' => false

    Right now your route will match 'my-endpoint' or 'single' and since there is no action set for these matches. Instead it will get the http method from the request and map to the corresponding controller methods inside the AbstractRestfulController onDispatch method.