RESTful API Router with Middleware Support
Lightweight API router with middleware pipeline and route parameters similar to Express.js
0
PHP Code
<?php
class Router {
private $routes = [];
private $middleware = [];
private $basePath = "";
public function __construct($basePath = "") {
$this->basePath = $basePath;
}
public function addMiddleware($middleware) {
$this->middleware[] = $middleware;
}
public function addRoute($method, $path, $handler, $middleware = []) {
$this->routes[] = [
"method" => strtoupper($method),
"path" => $path,
"handler" => $handler,
"middleware" => $middleware
];
}
public function get($path, $handler, $middleware = []) {
$this->addRoute("GET", $path, $handler, $middleware);
}
public function post($path, $handler, $middleware = []) {
$this->addRoute("POST", $path, $handler, $middleware);
}
public function dispatch($requestMethod, $requestUri) {
$uri = str_replace($this->basePath, "", parse_url($requestUri, PHP_URL_PATH));
$uri = rtrim($uri, "/") ?: "/";
$method = strtoupper($requestMethod);
foreach ($this->routes as $route) {
if ($route["method"] !== $method) continue;
$pattern = $this->compilePattern($route["path"]);
if (preg_match($pattern, $uri, $matches)) {
$params = array_filter($matches, "is_string", ARRAY_FILTER_USE_KEY);
$middlewareChain = array_merge($this->middleware, $route["middleware"]);
return $this->runMiddleware($middlewareChain, $route["handler"], $params);
}
}
return $this->notFound();
}
private function compilePattern($path) {
$path = preg_replace("/\{([a-z]+)\}/", "(?P<$1>[^/]+)", $path);
return "#^" . $path . "$#";
}
private function runMiddleware($middleware, $handler, $params) {
$next = function($params) use ($handler) {
return call_user_func($handler, $params);
};
foreach (array_reverse($middleware) as $mw) {
$next = function($params) use ($mw, $next) {
return call_user_func($mw, $params, $next);
};
}
return $next($params);
}
private function notFound() {
http_response_code(404);
return json_encode(["error" => "Route not found"]);
}
}
Explanation
This router implements a clean, middleware-based architecture similar to Express.js. It supports route parameters, middleware chaining, and all HTTP methods. The middleware pipeline allows for cross-cutting concerns like authentication and logging to be handled separately from route handlers.