Hi,
I appreciate the warm welcome. 
The reason I was looking at grouping routes is that I want to apply the same middleware to every route in a group. For example, I’ve been considering an approach like this:
<?php
declare(strict_types=1);
namespace Admin\Middleware;
use Mezzio\Router\RouteResult;
use Override;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use function str_starts_with;
final readonly class AdminMiddleware implements MiddlewareInterface
{
public function __construct(
private AllowOnlyAdminMiddleware $alternative,
) {
}
#[Override]
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
/** @var ?RouteResult $routeResult */
$routeResult = $request->getAttribute(RouteResult::class);
if (str_starts_with($routeResult->getMatchedRouteName(), 'admin')) {
return $this->alternative->process($request, $handler);
}
return $handler->handle($request);
}
}
Another approach I see now is building on what you provided:
public function registerRoutes(Application $app, string $basePath = '/blog'): void
{
$groupMiddleware = [Middleware\GroupMiddleware::class];
$app->get($basePath . '[/]', [...$groupMiddleware, Handler\ListPostsHandler::class], 'blog');
$app->get($basePath . '/{id:[^/]+}.html', [...$groupMiddleware, Handler\DisplayPostHandler::class], 'blog.post');
$app->get($basePath . '/tag/{tag:php}.xml', [...$groupMiddleware, Handler\FeedHandler::class], 'blog.feed.php');
$app->get($basePath . '/{tag:php}.xml', [...$groupMiddleware, Handler\FeedHandler::class], 'blog.feed.php.also');
$app->get($basePath . '/tag/{tag:[^/]+}/{type:atom|rss}.xml', [...$groupMiddleware, Handler\FeedHandler::class], 'blog.tag.feed');
$app->get($basePath . '/tag/{tag:[^/]+}', [...$groupMiddleware, Handler\ListPostsHandler::class], 'blog.tag');
$app->get($basePath . '/{type:atom|rss}.xml', [...$groupMiddleware, Handler\FeedHandler::class], 'blog.feed');
$app->get($basePath . '/search[/]', [...$groupMiddleware, Handler\SearchHandler::class], 'blog.search');
}
Does this approach align with how grouping and middleware are typically handled in Mezzio? Or is there a more conventional way to do this?