Routing paths aliases

Here is the problem.
I got two route paths to use for the same source - first frontend side - SEO friendly “/paper_bag_laminate”, second backend side for internal dynamic redirections “/articles/{item}/{feature}”. Does anybody know any elegant way to declare one as an alias of another to be able to trigger the same source without a need to re-declare it?

You could invoke a single action controller (instead of closures).

I was counting on you to be quite frank :). Even if, how can I avoid than double call of the same action within two different paths declaration ?

I’m not sure what you mean. Normally only one action (route) is executed per HTTP request.

Yes but as I said, I wish to have a possibility to call the same action by two different routes without a need to repeat the same callback body

    $app->map(['GET', 'POST'], '/paper_bags_laminate', function (Request $request, Response $response) {
        return $this->get(ArticleController::class)->add($request, $response, 1, 'paperbag');
    })->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));


    $app->map(['GET', 'POST'], '/article/{item}/{feature}', function (Request $request, Response $response, array $args) {
        return $this->get(ArticleController::class)->add($request, $response, $args['item'], $args['feature']);
    })->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));

The map method it’s interesting to handles multiple HTTP request methods. However, I never used it (yet).

Maybe you can do something like this:

(I do not tested the code, it’s just an idea)

  • In your routes:
    $app->map(['GET', 'POST'], '/paper_bags_laminate', 'ArticleController:add')
        ->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));


    $app->map(['GET', 'POST'], '/article/{item}/{feature}', 'ArticleController:add')
        ->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));

  • In your class:
...
class ArticleController
{
    public function add(Request $request, Response $response, array $args): Response
    {
        ...
        $item = $args['item'] ?? 1;
        $feature = $args['feature'] ?? 'paperbag';
        ...
    }
}
...

Or even you can do one path for each http method and then group the routes like this:

    $app->group('/paper_bags_laminate', function () use ($app) {
        $app->get('', 'ArticleController:get');
        $app->post('', 'ArticleController:add');
    })->addMiddleware($container->get(ValidationMiddleware::class))
      ->addMiddleware($container->get(CSRFMiddleware::class));

    $app->group('/article/{item}/{feature}', function () use ($app) {
        $app->get('', 'ArticleController:get');
        $app->post('', 'ArticleController:add');
    })->addMiddleware($container->get(ValidationMiddleware::class))
      ->addMiddleware($container->get(CSRFMiddleware::class));
1 Like

Thank you so much for your response. However both approaches still require two separate route declarations :slight_smile: and this is my, maybe not issue but something I wish to avoid. I was hoping there exists a kind of solution (that I am not perhaps aware of) similar to :slight_smile:

    $app->map(['GET', 'POST'], ['/article/{item}/{feature}', '/paper_bags_laminate'], 'ArticleController:add')
        ->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));

anyway, once again thank you, especially that on the other hand, maybe, once again maybe, you made me convinced for the shorter syntax meaning:

    $app->map(['GET', 'POST'], '/article/{item}/{feature}', 'ArticleController:add')
        ->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));

instead of:

    $app->map(['GET', 'POST'], '/paper_bags_laminate', function (Request $request, Response $response) {
        return $this->get(ArticleController::class)->add($request, $response, 1, 'paperbag');
    })->setName('article.article.add')
        ->addMiddleware($container->get(ValidationMiddleware::class))
        ->addMiddleware($container->get(CSRFMiddleware::class));