1

I have the following routing config in my project:

'router' => array(
    'routes' => array(
        'home' => array(
            'type' => 'Zend\Mvc\Router\Http\Literal',
            'options' => array(
                'route' => '/',
                'defaults' => array(
                    '__NAMESPACE__' => 'MyApp\Controller',
                    'controller' => 'Default',
                    'action' => 'default',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'api' => array(
                    'type' => 'Zend\Mvc\Router\Http\Segment',
                    'options' => array(
                        'route' => 'api/:action[/:id]',
                        'defaults' => array(
                            '__NAMESPACE__' => 'MyApp\Controller',
                            'controller' => 'Api',
                            'action' => 'index',
                        ),
                    ),
                    'may_terminate' => true,
                ),
                'default' => array(
                    'type' => 'Zend\Mvc\Router\Http\Segment',
                    'options' => array(
                        'route' => '[:id]',
                        'defaults' => array(
                            '__NAMESPACE__' => 'MyApp\Controller',
                            'controller' => 'Default',
                            'action' => 'default',
                        ),
                    ),
                    'may_terminate' => true,
                ),
            ),
        ),
    ),
),

When I make a call to http://localhost/api/foo/bar I get the response from the DefaultController. I have stripped my application until this is the only route (removed home/default, and made it an only route for the application) but it is ignored.

The desired outcome is that calls to /api... go to the Api controller, but all other calls go to the Default Controller.

There are no errors being thrown as far as I can see (looking at apache2 logs)

Any suggestions as to what might be wrong?

1 Answers1

1

I think it's because your default route id has no constraints, so it's matching everything. Try adding this after your default route.

'constraints' => ['id' => '[0-9]'],

dualmon
  • 1,225
  • 1
  • 8
  • 16
  • I'm afraid that wouldn't work - I need it to match anything that's not matched by the segment routes - it's working as a CMS - and the "id" can be anything (except "api" naturally) - essentially that route is a catch-all – Paul Merryfellow Apr 25 '15 at 14:52
  • Okay, then your constraint needs to be a clever regex then. See http://stackoverflow.com/questions/16930563/regex-match-anything-except-specific-string – dualmon Apr 25 '15 at 15:01
  • I may have to go with this, but it's a bit of an inconvenience that I have to add an exception to the route every time I add another segment – Paul Merryfellow Apr 26 '15 at 18:22
  • Unless I make the Default Controller handle errors, and intercept the 404 instead of routing a default catch-all. This seems messy to me though – Paul Merryfellow Apr 26 '15 at 18:25
  • Or you make a distinguishing segment before the default route like /content or /post or /whatnot – dualmon Apr 26 '15 at 18:33
  • Ahh, or the Regex! if I matched, for example, /_([a-z0-9]*) (or whatever the regex happens to be) - anything prefixed with a "_" - as an exception, that will allow me to prefix all "system" routes without having to bugger about changing regexes each time. – Paul Merryfellow Apr 26 '15 at 18:39
  • And that's what I did - Cheers dualmon, I matched using the expression: "^/?[^_]([a-z0-9-])*$" - since I don't allow underscores in the general URLs, I can just negate them from the Default/Wildcard (now Regex) route, and the default controller catches anything, except URLs with an underscore in them, which I route to specific purposes. – Paul Merryfellow Apr 26 '15 at 19:00
  • Glad you found a solution that works for you, even if it's unconventional :-) – dualmon Apr 26 '15 at 19:07