During development, developers often need to create sets of visually similar routes. The traditional way is creating each route, one by one, like in the below example:
$app->post('/product/create', CreateProductHandler::class, 'product:create');
$app->delete('/product/delete/{id}', DeleteProductHandler::class, 'product:delete');
$app->patch('/product/update/{id}', UpdateProductHandler::class, 'product:update');
$app->get('/product/view/{id}', GetProductHandler::class, 'product:view');
Besides the features provided by mezzio/mezzio-fastroute
, dot-router
offers route groups, which are collections of routes that (partially) share the same path.
In order to use this feature, first get an instance of the Dot\Router\RouteCollector
using the below code:
/** @var \Dot\Router\RouteCollectorInterface $routeCollector */
$routeCollector = $container->get(\Dot\Router\RouteCollectorInterface::class);
Then rewrite the above routes using the below code:
$routeCollector->group('/product')
->post('/create', CreateProductHandler::class, 'product:create');
->delete('/delete/{id}', DeleteProductHandler::class, 'product:delete');
->patch('/update/{id}', UpdateProductHandler::class, 'product:update');
->get('/view/{id}', GetProductHandler::class, 'product:view');
Note that /product becomes the group prefix and the routes only specify part that is specific only to them.
When dot-router
registers the routes, it will automatically prepend the prefix to each route path.
Besides sharing the same path, sometimes routes may need to share handlers/middlewares too.
A good example is the usage presence of CheckOwnerMiddleware
in the below example:
$app->post('/product/create', CreateProductHandler::class, 'product:create');
$app->delete('/product/delete/{id}', [CheckOwnerMiddleware::class, DeleteProductHandler::class], 'product:delete');
$app->patch('/product/update/{id}', [CheckOwnerMiddleware::class, UpdateProductHandler::class], 'product:update');
$app->get('/product/view/{id}', [CheckOwnerMiddleware::class, GetProductHandler::class], 'product:view');
Just like in the first example, the routes are similar but this time there is CheckOwnerMiddleware
, a middleware used by three out of the four routes.
For such cases, dot-router
provides for specific routes the ability to exclude a middleware from their pipeline.
Using this feature, we can rewrite the above example like this:
$routeCollector->group('/product', CheckOwnerMiddleware::class)
->post('/create', CreateProductHandler::class, 'product:create', CheckOwnerMiddleware::class)
->delete('/delete/{id}', DeleteProductHandler::class, 'product:delete')
->patch('/update/{id}', UpdateProductHandler::class, 'product:update')
->get('/view/{id}', GetProductHandler::class, 'product:view');
Note the second argument of the group
method is CheckOwnerMiddleware::class
.
This way all group middlewares will be prepended to the route's handler, so this is the equivalent of using:
$app->post('/product/create', [CheckOwnerMiddleware::class, CreateProductHandler::class], 'product:create')