HTTP routing, route matching, middleware, and URL generation. These classes provide comprehensive routing functionality including parameter binding, middleware chains, and named routes for your Forge Engine applications.
The main router class that manages route registration, matching, and dispatching. The Router provides a fluent interface for defining routes with various HTTP methods, middleware, and parameter constraints.
Register a GET route.
$router = new Router();
// Simple closure route
$router->get('/', function() {
    return 'Welcome to Forge Engine!';
});
// Controller route
$router->get('/users', [UserController::class, 'index']);
// Named route
$router->get('/users', [UserController::class, 'index'])->name('users.index');Register a POST route.
$router->post('/users', [UserController::class, 'store']);
$router->post('/login', [AuthController::class, 'login'])->name('auth.login');Register a PUT route.
$router->put('/users/{id}', [UserController::class, 'update']);
$router->put('/posts/{id}', [PostController::class, 'update'])->name('posts.update');Register a DELETE route.
$router->delete('/users/{id}', [UserController::class, 'destroy']);
$router->delete('/posts/{id}', [PostController::class, 'destroy'])->name('posts.destroy');Define routes with parameters.
// Required parameter
$router->get('/users/{id}', function($id) {
    return "User ID: {$id}";
});
// Optional parameter
$router->get('/posts/{id?}', function($id = null) {
    return $id ? "Post ID: {$id}" : "All posts";
});
// Multiple parameters
$router->get('/users/{user}/posts/{post}', function($user, $post) {
    return "User: {$user}, Post: {$post}";
});Add constraints to route parameters.
// Numeric constraint
$router->get('/users/{id}', function($id) {
    return "User ID: {$id}";
})->where('id', '[0-9]+');
// Alpha constraint
$router->get('/posts/{slug}', function($slug) {
    return "Post slug: {$slug}";
})->where('slug', '[a-z-]+');
// Multiple constraints
$router->get('/users/{id}/posts/{slug}', function($id, $slug) {
    return "User: {$id}, Post: {$slug}";
})->where([
    'id' => '[0-9]+',
    'slug' => '[a-z-]+'
]);Create a group of routes with shared attributes.
// Prefix grouping
$router->group(['prefix' => 'admin'], function($router) {
    $router->get('/dashboard', [AdminController::class, 'dashboard']);
    $router->get('/users', [AdminController::class, 'users']);
    $router->post('/users', [AdminController::class, 'createUser']);
});
// Middleware grouping
$router->group(['middleware' => 'auth'], function($router) {
    $router->get('/profile', [ProfileController::class, 'show']);
    $router->put('/profile', [ProfileController::class, 'update']);
    $router->get('/settings', [SettingsController::class, 'index']);
});
// Namespace grouping
$router->group(['namespace' => 'App\\Controllers\\Admin'], function($router) {
    $router->get('/dashboard', 'DashboardController@index');
    $router->get('/users', 'UserController@index');
    $router->get('/posts', 'PostController@index');
});
// Combined grouping
$router->group([
    'prefix' => 'api/v1',
    'middleware' => 'api',
    'namespace' => 'App\\Controllers\\Api'
], function($router) {
    $router->get('/users', 'UserController@index');
    $router->get('/posts', 'PostController@index');
    $router->get('/comments', 'CommentController@index');
});Represents a single route with its URI, HTTP methods, action, and middleware. The Route class provides methods for configuring individual routes with names, middleware, and parameter constraints.
Give a name to the route for URL generation.
// Named route
$router->get('/users/{id}', [UserController::class, 'show'])->name('users.show');
$router->get('/posts/{slug}', [PostController::class, 'show'])->name('posts.show');
$router->post('/login', [AuthController::class, 'login'])->name('auth.login');Add middleware to the route.
// Single middleware
$router->get('/admin', [AdminController::class, 'index'])->middleware('auth');
// Multiple middleware
$router->get('/admin/users', [AdminController::class, 'users'])
    ->middleware(['auth', 'admin']);
// Middleware with parameters
$router->get('/api/users', [ApiController::class, 'users'])
    ->middleware('throttle:60,1'); // 60 requests per minuteAdd a constraint to a route parameter.
$router->get('/users/{id}', function($id) {
    return "User ID: {$id}";
})->where('id', '[0-9]+');
$router->get('/posts/{slug}', function($slug) {
    return "Post slug: {$slug}";
})->where('slug', '[a-z0-9-]+');Get the name of the route.
$route = $router->get('/users', [UserController::class, 'index'])->name('users.index');
$name = $route->getName(); // "users.index"Get the URI pattern of the route.
$route = $router->get('/users/{id}', [UserController::class, 'show']);
$uri = $route->getUri(); // "/users/{id}"Get the action of the route.
$route = $router->get('/users', [UserController::class, 'index']);
$action = $route->getAction(); // [UserController::class, "index"]Manages a collection of routes and provides methods for matching requests against registered routes. The RouteCollection handles route compilation, parameter extraction, and route matching logic.
Add a route to the collection.
$collection = new RouteCollection();
// Create and add route
$route = new Route('GET', '/users', [UserController::class, 'index']);
$collection->add($route);
// Add named route
$route = new Route('GET', '/users/{id}', [UserController::class, 'show']);
$route->name('users.show');
$collection->add($route);Find a matching route for the given request.
$request = new Request('GET', '/users/123');
$route = $collection->match($request);
if ($route) {
    // Route found
    $parameters = $route->parameters();
    $controller = $route->getAction();
} else {
    // No matching route
    throw new NotFoundException();
}Get a route by its name.
$route = $collection->getByName('users.show');
if ($route) {
    $url = $route->url(['id' => 123]);
}Compile all routes for faster matching.
// Add routes
$collection->add($route1);
$collection->add($route2);
$collection->add($route3);
// Compile for performance
$collection->compile();
// Now matching will be faster
$route = $collection->match($request);Generate URLs for named routes with parameters. The routing system provides methods for creating URLs to named routes, making it easy to generate links in your application.
Generate a URL for a named route.
// Define named routes
$router->get('/users/{id}', [UserController::class, 'show'])->name('users.show');
$router->get('/posts/{slug}/comments/{id}', [CommentController::class, 'show'])
    ->name('posts.comments.show');
// Generate URLs
$url = $router->url('users.show', ['id' => 123]); // "/users/123"
$url = $router->url('posts.comments.show', ['slug' => 'hello-world', 'id' => 456]); // "/posts/hello-world/comments/456"Alias for url() method.
$url = $router->route('users.show', ['id' => 123]); // "/users/123"
$url = $router->route('users.index'); // "/users"Get the current matched route.
$currentRoute = $router->current();
if ($currentRoute) {
    $name = $currentRoute->getName();
    $uri = $currentRoute->getUri();
    $parameters = $currentRoute->parameters();
}Middleware provides a convenient mechanism for filtering HTTP requests entering your application. Routes can be protected with middleware for authentication, rate limiting, and other cross-cutting concerns.
Define middleware classes that implement the middleware interface.
namespace App\Middleware;
use Forge\Http\Request;
use Forge\Http\Response;
class AuthMiddleware
{
    public function handle(Request $request, callable $next): Response
    {
        if (!$request->user()) {
            return new Response('Unauthorized', 401);
        }
        
        return $next($request);
    }
}
class RateLimitMiddleware
{
    private $maxAttempts = 60;
    private $decayMinutes = 1;
    
    public function handle(Request $request, callable $next): Response
    {
        $key = $this->resolveRequestSignature($request);
        
        if ($this->tooManyAttempts($key, $this->maxAttempts)) {
            return new Response('Too Many Attempts', 429);
        }
        
        $this->hit($key, $this->decayMinutes * 60);
        
        $response = $next($request);
        
        return $this->addHeaders($response, $key, $this->maxAttempts);
    }
    
    private function resolveRequestSignature(Request $request): string
    {
        return 'rate_limit:' . $request->ip();
    }
    
    private function tooManyAttempts(string $key, int $maxAttempts): bool
    {
        return $this->attempts($key) >= $maxAttempts;
    }
    
    private function hit(string $key, int $decaySeconds): void
    {
        // Implementation for rate limiting
    }
    
    private function attempts(string $key): int
    {
        // Implementation to get current attempts
        return 0;
    }
    
    private function addHeaders(Response $response, string $key, int $maxAttempts): Response
    {
        $response->headers['X-RateLimit-Limit'] = $maxAttempts;
        $response->headers['X-RateLimit-Remaining'] = $maxAttempts - $this->attempts($key);
        
        return $response;
    }
}Register middleware in the application.
// In service provider or bootstrap
$container->bind('middleware.auth', AuthMiddleware::class);
$container->bind('middleware.rate_limit', RateLimitMiddleware::class);
$container->bind('middleware.cors', CorsMiddleware::class);
// Register middleware groups
$container->bind('middleware.web', [
    'middleware.cors',
    'middleware.csrf'
]);
$container->bind('middleware.api', [
    'middleware.cors',
    'middleware.rate_limit'
]);Common patterns and examples for working with the Routing system.
// routes.php
use Forge\Routing\Router;
use Forge\Routing\RouteCollection;
$router = new Router();
$collection = new RouteCollection();
// Define routes
$router->get('/', function() {
    return view('home');
})->name('home');
$router->get('/about', function() {
    return view('about');
})->name('about');
$router->get('/contact', function() {
    return view('contact');
})->name('contact');
// User routes
$router->get('/users', [UserController::class, 'index'])->name('users.index');
$router->get('/users/{id}', [UserController::class, 'show'])->name('users.show');
$router->get('/users/create', [UserController::class, 'create'])->name('users.create');
$router->post('/users', [UserController::class, 'store'])->name('users.store');
$router->get('/users/{id}/edit', [UserController::class, 'edit'])->name('users.edit');
$router->put('/users/{id}', [UserController::class, 'update'])->name('users.update');
$router->delete('/users/{id}', [UserController::class, 'destroy'])->name('users.destroy');
// API routes
$router->group([
    'prefix' => 'api/v1',
    'middleware' => 'api'
], function($router) {
    $router->get('/users', [ApiUserController::class, 'index']);
    $router->get('/users/{id}', [ApiUserController::class, 'show']);
    $router->post('/users', [ApiUserController::class, 'store']);
    $router->put('/users/{id}', [ApiUserController::class, 'update']);
    $router->delete('/users/{id}', [ApiUserController::class, 'destroy']);
});// Advanced routing with constraints and middleware
$router->get('/posts/{year}/{month}/{slug}', [PostController::class, 'show'])
    ->name('posts.archive')
    ->where([
        'year' => '[0-9]{4}',
        'month' => '[0-9]{2}',
        'slug' => '[a-z0-9-]+'
    ]);
// Protected routes with multiple middleware
$router->group(['middleware' => ['auth', 'verified']], function($router) {
    $router->get('/dashboard', [DashboardController::class, 'index']);
    $router->get('/profile', [ProfileController::class, 'show']);
    $router->put('/profile', [ProfileController::class, 'update']);
    
    $router->group(['prefix' => 'settings'], function($router) {
        $router->get('/', [SettingsController::class, 'index']);
        $router->put('/general', [SettingsController::class, 'updateGeneral']);
        $router->put('/security', [SettingsController::class, 'updateSecurity']);
        $router->put('/notifications', [SettingsController::class, 'updateNotifications']);
    });
});
// Admin routes with role-based middleware
$router->group([
    'prefix' => 'admin',
    'middleware' => ['auth', 'role:admin']
], function($router) {
    $router->get('/dashboard', [AdminDashboardController::class, 'index']);
    $router->resource('users', AdminUserController::class);
    $router->resource('posts', AdminPostController::class);
    $router->get('/analytics', [AnalyticsController::class, 'index']);
});
// Resource routes (RESTful)
$router->resource('posts', PostController::class);
$router->resource('comments', CommentController::class)->only(['index', 'show', 'store', 'destroy']);
$router->resource('tags', TagController::class)->except(['create', 'edit']);// In PHP views
Home
View User
Read Post
// In templates with helper function
Home
View User
Post
// With route helper
All Users
Create User
Edit User
// Conditional URLs
has('admin.dashboard')): ?>
    Admin Dashboard
Recommended patterns and guidelines for working with the Routing system.