zendframework / zend-router

Standalone routing implementation for HTTP and console requests
BSD 3-Clause "New" or "Revised" License
32 stars 20 forks source link

Action key always returns index, problematic for RESTful controllers #17

Closed seaneble closed 7 years ago

seaneble commented 8 years ago

The RESTful controller of MVC knows two different behaviours:

For me, using the latest and greatest versions of both components, this is a problem. For some reason, the router always sets the action key of the RouteMatch, so RESTful actions are never executed.

This it the RouteMatch I get for http://somedomain/:

object(Zend\Router\Http\RouteMatch)#128 (3) {
    ["length":protected]=> int(1)
    ["params":protected]=> array(2) {
        ["controller"]=> string(38) "Application\Controller\IndexController"
        ["action"]=> string(5) "index"
    }
    ["matchedRouteName":protected]=> string(4) "home"
}

The respective config is this:

return [
    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                    ],
                ],
            ],
        ],
    ],

I also tried to overwrite the index key deliberately by setting it to

                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action' => 'getList',
                    ],

but the RouteMatch always stays the same. Why? Is it me or the code?

Any help is very welcome.

adamlundrigan commented 8 years ago

There's little in the way of documentation for or recent information on AbstractRestfulController so I did this: using the latest version of the skeleton, I added a route to the module config:

            'ping' => [
                'type' => Segment::class,
                'options' => [
                    'route'    => '/ping[/:id]',
                    'defaults' => [
                        'controller' => Controller\PingController::class,
                    ],
                ],
            ],

And added PingController:

<?php
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractRestfulController;

class PingController extends AbstractRestfulController
{
    public function getList()
    {
        return [
            'now' => date(\DateTime::ISO8601)
        ];
    }
}

(and added that controller to the controller factory)

... and it's "working". I dump the RouteMatch from inside getList and I get this:

Zend\Router\Http\RouteMatch Object
(
    [length:protected] => 5
    [params:protected] => Array
        (
            [controller] => Application\Controller\PingController
        )

    [matchedRouteName:protected] => ping
)

However, I also get a Zend\View runtime exception:

Unable to render template "application/ping/get-list"; resolver could not resolve to a file

I added the ViewJsonStrategy to the view manager but still received the same error. Maybe this stopped working way back when renderer selection based on Accept header was removed from those strategies (PR)? Or maybe I'm just not configuring the controller properly. In either case, AbstractRestfulController probably should be updated to use AcceptableViewModelSelector.

A quick Google didn't turn up any recent articles or mentions of AbstractRestfulController. I suspect that people have long since moved on to packages like ZfrRest or zf-rest or even rolling their own (eg: zend-router can do routing based on HTTP Method)

Xerkus commented 7 years ago

Router does not set parameters on its own, none of the zend-mvc versions have 'index' string either. It is either from route configuration or some user registered listener in mvc application