0
votes

In my Api I have multiple child routes specified in module.config.php. When accessing the Api with a not valid route I get the 404 of my Application module but I would like to return a 404 in json. My idea is to have a catch all not valid routes and forward to a controller action to return a valid json 404 response.

My routes config looks as following:

'router' => array(
        'routes' => array(
            'api-host' => array(
                'type'    => 'Hostname',
                'options' => array(
                    'route'    => 'api.efeedback.de',
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'index' => array(
                        'type' => 'Segment',
                        'options' => array(
                            'route' => '/',
                            'defaults' => array(
                                'controller' => 'Api\Controller\Index',
                                'action' => 'index',
                            ),
                        ),
                    ),
                    'imports' => array(
                        'type' => 'Segment',
                        'options' => array(
                            'route' => '/imports/:product_id',
                            'constraints' => array(
                                'product_id' => '[0-9]+',
                            ),
                            'defaults' => array(
                                'controller' => 'Api\Controller\Import',
                            ),
                        ),
                    ),
                    'reports' => array(
                        'type' => 'Segment',
                        'options' => array(
                            'route' => '/reports',
                            'defaults' => array(
                                'controller' => 'Api\Controller\Report',
                                'auth' => true,
                            ),
                        ),
                        'may_terminate' => false,
                        'child_routes' => array(
                            'ratings' => array(
                                'type' => 'Segment',
                                'options' => array(
                                    'route' => '/ratings',
                                    'defaults' => array(
                                        'controller' => 'Api\Controller\Report',
                                        'auth' => true,
                                    ),
                                ),
                                'may_terminate' => false,
                                'child_routes' => array(
                                    'products' => array(
                                        'type' => 'Segment',
                                        'options' => array(
                                            'route' => '/products/:product_id',
                                            'constraints' => array(
                                                'product_id' => '[0-9]+',
                                            ),
                                            'defaults' => array(
                                                'controller' => 'Api\Controller\Report',
                                                'action' => 'products'
                                            ),
                                        ),
                                        'may_terminate' => false,
                                        'child_routes' => array(
                                            'advisors' => array(
                                                'type' => 'Segment',
                                                'options' => array(
                                                    'route' => '/advisors[/:advisor_id]',
                                                    'constraints' => array(
                                                        'advisor_id' => '[0-9]+',
                                                    ),
                                                    'defaults' => array(
                                                        'controller' => 'Api\Controller\Report',
                                                        'action' => 'advisors'
                                                    ),
                                                ),
                                            ),
                                            'providers' => array(
                                                'type' => 'Segment',
                                                'options' => array(
                                                    'route' => '/providers[/:provider_id]',
                                                    'constraints' => array(
                                                        'provider_id' => '[0-9]+',
                                                    ),
                                                    'defaults' => array(
                                                        'controller' => 'Api\Controller\Report',
                                                        'action' => 'providers'
                                                    ),
                                                ),
                                            ),
                                        ),
                                    ),
                                ),
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),

The wildcard type somehow worked but not for all routes. But wildcard is deprecated.

How can I achieve this?

1
Will that also return json when an Application route does not match?KiwiJuicer
You will need to try it, I haven't tested it myself, alternatively try intercepting DISPATCH_ERROR event and modifying response when it occurs.Adam
No, it will also apply for my other modules. I have used a regex type now and this catches all not matching routesKiwiJuicer

1 Answers

1
votes

I have decided to use the Regex route type and to put it on the very top of my child routes:

'catch-all-no-match' => array(
    'type' => 'Regex',
    'options' => array(
        'regex' => '(?<content>.+)',
        'defaults' => array(
            'controller' => 'Api\Controller\Index',
            'action' => 'catch-all-no-match',
        ),
        'spec' => '%content%',
    ),
),

Don't put it somewhere else as it would match before the other routes get checked.