Search code examples
phprestzend-framework2restful-architecture

REST Routing fails in ZF2 Rest Skeleton


I configured the Resftul module (https://github.com/scaraveos/ZF2-Restful-Module-Skeleton) with the following module.config.php . But as I want to access "public/rest/article.json" the routing fails.

Does someone have a clue for me? Controller is given.

return array(
    'errors' => array(
        'post_processor' => 'json-pp',
        'show_exceptions' => array(
            'message' => true,
            'trace'   => true
        )
    ),
    'di' => array(
        'instance' => array(
            'alias' => array(
                'json-pp'  => 'Rest\PostProcessor\Json',
                'image-pp' => 'Rest\PostProcessor\Image',
            )
        )
    ),
    'controllers' => array(
        'invokables' => array(
            'article' => 'Rest\Controller\ArticleController',
        )
    ),
    'router' => array(
        'routes' => array(
            'restful' => array(
                'type'    => 'Zend\Mvc\Router\Http\Segment',
                'options' => array(
                    'route'       => '/[:controller][.:formatter][/:id]',
                    'constraints' => array(
                        'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'formatter'  => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'id'         => '[a-zA-Z0-9_-]*'
                    ),
                ),
            ),
        ),
    ),
);

autoload_classmap is

'Rest\Controller\ArticleController' => __DIR__ . '/src/Rest/Controller/ArticleController.php',

Solution

  • You can do what you want, but there's a better way to handle REST request, using the Content Type header to decide what format is to be shown. ZF2 is good at doing this using View Strategies:

    http://framework.zend.com/manual/2.0/en/modules/zend.view.quick-start.html#creating-and-registering-alternate-rendering-and-response-strategies

    You can use a different strategy depending upon which content type is requested, which is what you should be doing with REST APIs.

    You could rewrite your route to use something like this:

    'route' => '/[:controller[.:format][/:id]]',
    'constraints' => array(
        'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
        'format' => '(xml|json|sphp)',
        'id' => '[1-9][0-9]*',
    ),
    'defaults' => array(
        'controller' => 'Rest\Controller\ArticleController',
        'format' => 'xml',
    ),
    

    You could then use routes such as '/articles.json/9' or /articles/xml