Routing
Lalaz provides a powerful and expressive routing system. Routes are defined in files inside the routes/ directory and are automatically loaded based on your configuration.
Defining Routes
Routes are defined in a route file that returns a closure receiving a Router instance:
<?php declare(strict_types=1);
use Lalaz\Web\Routing\Router;
return function (Router $router): void {
$router->get('/', fn() => ['message' => 'Hello, World!']);
};Basic Routes
The router provides methods for all standard HTTP verbs:
$router->get('/users', UserController::class . '@index');
$router->post('/users', UserController::class . '@store');
$router->put('/users/{id}', UserController::class . '@update');
$router->patch('/users/{id}', UserController::class . '@update');
$router->delete('/users/{id}', UserController::class . '@destroy');
$router->options('/users', UserController::class . '@options');
$router->head('/users', UserController::class . '@head');Any Method
Register a route that responds to any HTTP method:
$router->any('/webhook', WebhookController::class . '@handle');Multiple Methods
Register a route for specific HTTP methods:
$router->methods(['GET', 'POST'], '/form', FormController::class . '@handle');Route Parameters
Required Parameters
Use curly braces to define route parameters:
$router->get('/users/{id}', function (Request $request): array {
$id = $request->routeParam('id');
return ['user_id' => $id];
});
$router->get('/posts/{postId}/comments/{commentId}', function (Request $request): array {
$postId = $request->routeParam('postId');
$commentId = $request->routeParam('commentId');
return ['post' => $postId, 'comment' => $commentId];
});Parameter Patterns
Add regex constraints to parameters:
// Only numeric IDs
$router->get('/users/{id:\d+}', UserController::class . '@show');
// Alphanumeric slugs
$router->get('/posts/{slug:[a-z0-9-]+}', PostController::class . '@show');
// Catch-all path
$router->get('/files/{path:.+}', FileController::class . '@serve');Route Handlers
Routes accept several handler formats:
Closure Handlers
$router->get('/health', function (): array {
return ['status' => 'ok', 'timestamp' => date('c')];
});Controller String Syntax
$router->get('/users', UserController::class . '@index');
$router->get('/users/{id}', 'App\Controllers\UserController@show');Controller Array Syntax
$router->get('/users', [UserController::class, 'index']);Route Groups
Group routes with shared attributes like prefixes and middleware:
Simple Prefix
$router->group('/api', function (Router $router): void {
$router->get('/users', UserController::class . '@index'); // /api/users
$router->get('/posts', PostController::class . '@index'); // /api/posts
});With Attributes Array
$router->group([
'prefix' => '/admin',
'middleware' => [AuthMiddleware::class, AdminMiddleware::class]
], function (Router $router): void {
$router->get('/dashboard', AdminController::class . '@dashboard');
$router->get('/users', AdminController::class . '@users');
});Nested Groups
$router->group('/api', function (Router $router): void {
$router->group('/v1', function (Router $router): void {
$router->get('/users', UserControllerV1::class . '@index'); // /api/v1/users
});
$router->group('/v2', function (Router $router): void {
$router->get('/users', UserControllerV2::class . '@index'); // /api/v2/users
});
});Resource Routes
The resource() method registers standard RESTful routes for a controller:
$router->resource('users', UserController::class);This creates the following routes:
| Method | Path | Action | Description |
|---|---|---|---|
| GET | /users | index | List all users |
| GET | /users/create | create | Show create form |
| POST | /users | store | Create a user |
| GET | /users/ | show | Show a user |
| GET | /users/{userId}/edit | edit | Show edit form |
| PUT | /users/ | update | Update a user |
| PATCH | /users/ | update | Partial update |
| DELETE | /users/ | destroy | Delete a user |
Parameter Naming
The parameter name is derived from the resource name in singular form. For users, the parameter is userId. For posts, it would be postId.
Partial Resources
Use only or except to limit which routes are registered:
// Only these actions
$router->resource('users', UserController::class, only: ['index', 'show']);
// All except these actions (useful for APIs without HTML forms)
$router->resource('users', UserController::class, except: ['create', 'edit']);Attribute-Based Routing
Define routes directly on controller methods using PHP 8 attributes:
<?php
declare(strict_types=1);
namespace App\Controllers;
use Lalaz\Web\Routing\Attribute\Route;
class UserController
{
#[Route('/users', method: 'GET')]
public function index(): array
{
return ['users' => []];
}
#[Route('/users/{id}', method: 'GET')]
public function show(int $id): array
{
return ['user' => ['id' => $id]];
}
#[Route('/users', method: 'POST', middlewares: ['auth'])]
public function store(): array
{
return ['message' => 'User created'];
}
}Register Controllers
Register controllers with attribute routes in your configuration:
// config/app.php
return [
'router' => [
'controllers' => [
App\Controllers\UserController::class,
App\Controllers\PostController::class,
],
],
];Or register them manually:
$router->registerControllers([
App\Controllers\UserController::class,
App\Controllers\PostController::class,
]);Route Attribute Options
#[Route(
path: '/users/{id}', // URL path (required)
method: 'GET', // Single HTTP method
methods: ['GET', 'HEAD'], // Multiple HTTP methods
middlewares: ['auth', 'log'] // Middleware to apply
)]Route Middleware
Apply middleware to individual routes:
$router->get('/admin', AdminController::class . '@index', [
AuthMiddleware::class,
AdminMiddleware::class
]);Or to a group:
$router->group([
'prefix' => '/admin',
'middleware' => [AuthMiddleware::class]
], function (Router $router): void {
// All routes here require authentication
$router->get('/dashboard', AdminController::class . '@dashboard');
});Route Configuration
Routes are configured in config/app.php:
return [
'router' => [
// Route files to load
'files' => [
__DIR__ . '/../routes/api.php',
__DIR__ . '/../routes/web.php',
],
// Controllers with attribute routes
'controllers' => [
App\Controllers\UserController::class,
],
],
];Inspecting Routes
Use the CLI to list all registered routes:
php lalaz routes:listValidate route definitions:
php lalaz routes:validateRoute Caching
For production, cache your routes for better performance:
# Generate route cache
php lalaz route:cache
# Clear route cache
php lalaz route:cache:clearWARNING
Remember to clear the route cache after making changes to your route files.