Jacob
Jacob

Reputation: 920

zf2 AbstractRestfullController API routing

I am pretty new to zf2. I am trying to build a RESTful API for our contact management system. We are extending the AbstractRestfulController which uses getList(), get(), etc actions.

Everything works as I would expect it to with the exception of one url route. When I go to this url

/contacts

it successfully routes to the getList() method of my ContactsController. However when I go here.

/contacts/1253378/stats

it routes to the get() method of my StatsController. I would expect that url to route to the getList() method, which I would then return a list of stats.

I would expect adding an /idnumber to the end of that url would route to the get() method of my StatsController, which would return one stat with that id.

Basically I am trying to replicate what is laid out in this REST tutorial, under the But how do you deal with relations section.

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful

I am hoping my routes are not correct in my module.config.php file

'router' => array(
    'routes' => array(

        'contacts' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/contacts[/:id]',
                'constraints' => array(
                    'id'     => '[0-9]+',
                ),
                'defaults' => array(
                    'controller' => 'Contacts\Controller\ContactsController',
                ),
            ),
        ),

        'stats' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/contacts/[:id]/stats[/:id]',
                'constraints' => array(
                    'id'     => '[0-9]+',
                ),
                'defaults' => array(
                    'controller' => 'Contacts\Controller\StatsController',
                ),
            ),
        ),

    ),
),

Any help would be greatly appreciated.

Upvotes: 0

Views: 346

Answers (1)

Xerkus
Xerkus

Reputation: 2705

In your case problem is that id parameter conflicts, recommended way is to use specific parameter names, eg:

'router' => array(
    'routes' => array(
       'contacts' => array(
            'type'    => 'segment',
            'options' => array(
               'route'    => '/contacts[/:contactId]',
                'constraints' => array(
                    'contactId'     => '[0-9]+',
                ),
                'defaults' => array(
                    'controller' => 'Contacts\Controller\ContactsController',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'stats' => array(
                    'type'    => 'segment',
                    'options' => array(
                       'route'    => '/stats[/:statId]',
                       'constraints' => array(
                            'statId'     => '[0-9]+',
                        ),
                        'defaults' => array(
                            'controller' => 'Contacts\Controller\StatsController',
                        ),
                    ),
                ),
            ),
        ),
    ),
),

Url /contacts/1253378/stats will match contacts/stats route with contactId set to 1253378

To make that change work, you will need to set protected property identifierName in Contacts\Controller\ContactsController to 'contactId' and in Contacts\Controller\StatsController to statId

Now controllers will properly use separate variables for Id and everything should work fine.

Upvotes: 5

Related Questions