Strata uses a compiled Radix router. Fast lookups, zero regex on hot path. 0.01ms dispatch even with 1k routes.
Define routes directly on the App instance. Closures or controller classes both work.
use Strata\App;
$app = new App();
$app->get('/', fn() => 'Home');
$app->post('/users', fn(Request $r) => User::create($r->json()));
$app->put('/users/{id}', [UserController::class, 'update']);
$app->delete('/users/{id}', 'UserController@destroy');
$app->run();
Parameters are type-hinted. Strata auto-casts them.
$app->get('/users/{id}', function(int $id) {
return "User $id";
});
$app->get('/posts/{slug}', function(string $slug) {
return Post::findBySlug($slug);
});
/users/abc is hit, Strata returns 404 before your code runs. No is_numeric() checks needed.Group routes to apply prefixes and middleware.
$app->group('/api', function(App $api) {
$api->group('/v1', function(App $v1) {
$v1->get('/users', [UserController::class, 'index']);
$v1->post('/users', [UserController::class, 'store']);
})->middleware(AuthMiddleware::class);
});
This creates /api/v1/users with AuthMiddleware applied.
Name routes to generate URLs later.
$app->get('/users/{id}', [UserController::class, 'show'])->name('users.show');
// Later, in a template or controller:
$url = $app->route('users.show', ['id' => 5]); // /users/5
Typehint any service. If it’s in your PSR-11 container, Strata injects it.
use App\Repository\UserRepository;
use Psr\Log\LoggerInterface;
$app->get('/users/{id}', function(int $id, UserRepository $users, LoggerInterface $log) {
$log->info("Fetching user $id");
return $users->find($id);
});
Catch anything that didn’t match.
$app->fallback(function() {
return new Response(404, [], 'Not Found');
});