Core

Routing Service Provider

Router integration, URL generation and route definition services.

Responsibility

Works with the core Router service and routes loaded from app/Config/Routing.php. RoutingServiceProvider registers LocaleUrlStrategyInterface, UrlGenerator and alias url; these services are used by controllers, views, navigation and redirects for stable URL generation.

Route config

Application routes live in app/Config/Routing.php. The file returns callable(Router $router): void; applications can register plain routes, named routes, middleware and localized groups through the same router instance.

<?php

declare(strict_types=1);

use App\Controllers\ContactController;
use App\Controllers\HomeController;
use Lemonade\Framework\Routing\Router;
use Lemonade\Framework\Security\Csrf\CsrfMiddleware;

return static function (Router $router): void {
    $router->getNamed('home', '/', HomeController::class . '@index');
    $router->getNamed('contact.form', '/contact', ContactController::class . '@form');

    $router
        ->postNamed('contact.submit', '/contact', ContactController::class . '@submit')
        ->middleware(CsrfMiddleware::class);
};

Named routes

Named routes are used for URL generation. Prefer route names in views, navigation and redirects instead of manually concatenating paths; route names stay stable when the public path changes.

use Lemonade\Framework\Routing\UrlGenerator;

$url = $container->get('url');

$homeUrl = $url->route('home');
$contactUrl = $url->route('contact.form');

Route parameters

Routes support {name} parameters and {name:any} catch-all parameters. UrlGenerator::route() replaces placeholders and appends extra params as query string.

$router->getNamed(
    'article.detail',
    '/articles/{slug}',
    ArticleController::class . '@detail',
);

$url->route('article.detail', [
    'slug' => 'hello-world',
    'preview' => 1,
]);

// Result: /articles/hello-world?preview=1

Controller target

Route handlers use Controller@action syntax, commonly as HomeController::class . '@index'. The controller is resolved through the container, route params are passed into action arguments and the action must return a PSR response, scalar/stringable value or null.

$router->getNamed(
    'home',
    '/',
    HomeController::class . '@index',
);

HTTP methods

Router supports get, post, put, patch, delete, head, options and named variants such as getNamed() and postNamed(). Generic map() and mapNamed() are available when the method is dynamic.

$router->getNamed('contact.form', '/contact', ContactController::class . '@form');
$router->postNamed('contact.submit', '/contact', ContactController::class . '@submit');

Navigation usage

Navigation data can store route names and resolve URLs at render time. This keeps menus independent from concrete paths and allows localized URL generation when the application enables localized routing.

$items = [
    ['label' => 'Home', 'url' => $url->route('home')],
    ['label' => 'Contact', 'url' => $url->route('contact.form')],
];

Redirects

Controllers use the generated URL with the existing redirect() helper. There is no separate redirectToRoute() helper; generate the route URL first and pass it to redirect().

return $this->redirect(
    $this->url()->route('home'),
);

Unmatched routes

Router::match() throws RouteNotFoundException when no route matches. The HTTP kernel converts that exception to a 404 response; for GET/HEAD it first tries the framework convention fallback before failing.