Routing connects URLs to application logic. In Marwa Framework, routes are defined in routes/web.php and routes/api.php.
Routes are defined in:
routes/
├── web.php # Browser requests
├── api.php # REST API endpoints
└── console.php # CLI closures
<?php
use Marwa\Framework\Facades\Router;
use Marwa\Router\Response;
use App\Controllers\HomeController;
// Basic routes
Router::get('/', function() {
return Response::html('<h1>Welcome</h1>');
})->register();
Router::get('/about', function() {
return Response::html('<h1>About Us</h1>');
})->register();
Router::post('/contact', function() {
// Handle POST request
return Response::html('<h1>Thank you!</h1>');
})->register();
Marwa Framework supports all HTTP methods:
// GET requests
Router::get('/users', fn() => Response::json(['users' => []]))->register();
// POST requests
Router::post('/users', fn() => Response::json(['created' => true]))->register();
// PUT requests
Router::put('/users/{id}', fn($id) => Response::json(['id' => $id]))->register();
// PATCH requests
Router::patch('/users/{id}', fn($id) => Response::json(['updated' => true]))->register();
// DELETE requests
Router::delete('/users/{id}', fn($id) => Response::json(['deleted' => true]))->register();
// URL: /users/123
Router::get('/users/{id}', function($id) {
return Response::json(['user_id' => $id]);
})->register();
// URL: /posts/123/comments/456
Router::get('/posts/{postId}/comments/{commentId}', function($postId, $commentId) {
return Response::json([
'post_id' => $postId,
'comment_id' => $commentId
]);
})->register();
Router::get('/users/{id?}', function($id = null) {
if ($id) {
return Response::json(['user_id' => $id]);
}
return Response::json(['users' => []]);
})->register();
Name your routes for easy URL generation:
Router::get('/users/profile', function() {
return Response::html('<h1>Profile</h1>');
})->name('user.profile')->register();
Router::get('/dashboard', function() {
return Response::html('<h1>Dashboard</h1>');
})->name('dashboard')->register();
Group related routes with shared attributes:
// Group with prefix
Router::group(['prefix' => '/admin'], function() {
Router::get('/users', fn() => Response::html('Admin Users'))->register();
Router::get('/settings', fn() => Response::html('Admin Settings'))->register();
});
// Group with middleware
Router::group(['middleware' => ['auth']], function() {
Router::get('/profile', fn() => Response::html('Profile'))->register();
Router::post('/profile', fn() => Response::html('Profile Updated'))->register();
});
// Combined groups
Router::group([
'prefix' => '/api/v1',
'middleware' => ['api']
], function() {
Router::get('/users', fn() => Response::json(['users' => []]))->register();
});
Use controllers for cleaner code:
<?php
use App\Controllers\PostController;
use App\Controllers\UserController;
// Single action
Router::get('/posts', [PostController::class, 'index'])->register();
Router::get('/posts/{id}', [PostController::class, 'show'])->register();
Router::post('/posts', [PostController::class, 'store'])->register();
Router::put('/posts/{id}', [PostController::class, 'update'])->register();
Router::delete('/posts/{id}', [PostController::class, 'destroy'])->register();
Router::get('/users/{id}', function($id) {
return Response::json(['user_id' => $id]);
})->where('id', '[0-9]+')->register();
Router::get('/posts/{slug}', function($slug) {
return Response::json(['slug' => $slug]);
})->where('slug', '[a-z-]+')->register();
Router::get('/users/{id}/posts/{post}', function($id, $post) {
return Response::json(['user' => $id, 'post' => $post]);
})->where([
'id' => '[0-9]+',
'post' => '[a-z-]+'
])->register();
Catch-all route for 404:
Router::fallback(function() {
return Response::html('<h1>404 - Page Not Found</h1>', 404);
});
Force HTTPS for specific routes:
Router::group(['scheme' => 'https'], function() {
Router::post('/checkout', fn() => Response::html('Checkout'))->register();
});
View all routes from CLI:
php marwa route:list
<?php
use Marwa\Framework\Facades\Router;
use Marwa\Router\Response;
use App\Controllers\Api\UserController;
use App\Controllers\Api\PostController;
Router::group(['prefix' => '/api'], function() {
// Users
Router::get('/users', [UserController::class, 'index'])->register();
Router::get('/users/{id}', [UserController::class, 'show'])->register();
Router::post('/users', [UserController::class, 'store'])->register();
Router::put('/users/{id}', [UserController::class, 'update'])->register();
Router::delete('/users/{id}', [UserController::class, 'destroy'])->register();
// Posts
Router::get('/posts', [PostController::class, 'index'])->register();
Router::get('/posts/{id}', [PostController::class, 'show'])->register();
Router::post('/posts', [PostController::class, 'store'])->register();
});
Router::get('/health', function() {
return Response::json([
'status' => 'ok',
'timestamp' => time(),
'environment' => app()->environment()
]);
})->register();