RESTful API Router with Middleware Support

PHP Advanced 👁️ 1,428 views By system Added Just now

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.