GitHub

Routing

The routing system in TinyMVC is responsible for matching incoming HTTP requests to their corresponding handlers (closures or controller methods) and processing the response. It provides a fluent, expressive interface for defining routes with support for middleware, parameter binding, and route groups.

Basic Routing

Routes are typically defined in routes/web.php using URI patterns and closures or controller methods:

Closure Example

Route::get('foo', function (Request $request) {
    if ($request->has('name')) {
        return sprintf('Hello %s', $request->input('name'));
    }
    return 'Hello World';
});

Controller Method Example

Route::post('foo', [SomeController::class, 'store']);
Dependency Injection: The router automatically resolves both controller dependencies and route parameters through the dependency injection container.

Show All registered routes

To display all registered routes in your application, you can use the following command:

php spark route:list

HTTP Method Routing

The router provides methods for all standard HTTP verbs:

Basic Verbs

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Special Cases

// Match any HTTP method
Route::any($uri, $callback);

// Match specific methods
Route::match(['get', 'post'], $uri, $callback);

// Redirect routes
Route::redirect($from, $to, $status = 302);

// Resourceful routes
Route::resource($name, $controller);

// View rendering
Route::view($uri, $template);

// Group routes
Route::group($attributes, $closure);

Route Parameters

Routes can capture segments of the URI as parameters:

Required Parameters

Route::get('user/{id}', function ($id) {
    return "User {$id}";
});

Multiple Parameters

Route::get('posts/{postId}/comments/{commentId}', 
    function ($postId, $commentId) {
        // Logic here
    });
Parameter Matching: Parameters automatically match alphanumeric characters, hyphens, and underscores. The {id} parameter specifically matches numeric values.

Named Routes

Routes can be assigned names for easy URL generation:

Route::get('/profile', $callback)->name('profile');

URL Generation

Generate URLs for named routes with parameters:

// Basic route URL
$url = route_url('profile'); // returns string
$url = route('profile'); // returns Url object

// Parameterized route URL
$url = route_url('post.comment', [
    'postId' => 1, 
    'commentId' => 2
]);

Route Groups

Group routes to share common attributes:

Route::group([
    'middleware' => ['auth', 'role:admin'],
    'path' => '/admin',
    'name' => 'admin.'
], function() {
    Route::get('/dashboard', [AdminController::class, 'dashboard']);
    // More routes...
});

Available Group Attributes

Attribute Description Example
middleware Array of middlewares to apply to all routes ['auth', 'throttle']
path Prefix for all route paths '/api/v1'
method HTTP methods to apply to all routes ['get', 'post']
name Prefix for all route names 'api.'
callback Controller to use for all routes ApiController::class
template View template prefix 'admin/'

Resourceful Routing

Generate multiple routes for a resource controller:

Route::resource('photos', PhotoController::class, 
    name: 'photos',
    middleware: ['auth'],
    only: ['index', 'show'],
    except: ['destroy']
);

Resource Route Mapping

Verb Path Action Route Name
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{id} show photos.show
GET /photos/{id}/edit edit photos.edit
PUT/PATCH /photos/{id} update photos.update
DELETE /photos/{id} destroy photos.destroy

View Routes

Routes can directly render views or Fireline templates:

// Regular view
Route::view('/welcome', 'welcome');

// Fireline template
Route::fireline('/dashboard', 'dashboard');

Middleware

Assign middleware to routes:

Route::get('/admin', [AdminController::class, 'index'])
    ->middleware(['auth', 'admin']);
Middleware Groups: Middleware defined in route groups will be merged with route-specific middleware, with duplicates removed.

Route Matching Process

When a request comes in, the router:

  1. Iterates through all registered routes in the order they were defined
  2. Checks for a match on both HTTP method and URI pattern
  3. Extracts route parameters from the URI
  4. Applies any route-specific middleware
  5. Executes the route callback or renders the specified view
  6. Returns a Response object

Error Handling

The router throws specific exceptions for routing errors:

  • RouteNotFoundException - When no matching route is found
  • InvalidNamedRouteException - When generating a URL for a non-existent named route