power-modules / router
A modular router component for the Power Modules framework with encapsulated routing capabilities and explicit module integration
v1.1.1
2025-09-22 08:51 UTC
Requires
- php: ^8.4
- league/route: ^6.2
- power-modules/framework: ^1.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.87
- laminas/laminas-diactoros: ^3.6
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.3
Suggests
- laminas/laminas-diactoros: PSR-7 implementation used in examples and tests
- laminas/laminas-httphandlerrunner: PSR-7 response emitter for HTTP applications
README
A modular router component for the Power Modules framework that provides HTTP routing capabilities with strict module encapsulation and dependency injection integration.
🔌 Perfect Integration: Built specifically for the Power Modules ecosystem with automatic route discovery, module-scoped controllers, and composable middleware stacks.
✨ Why Modular Router?
- 🏗️ Module-Centric: Routes are owned and defined by individual modules
- 🔒 Encapsulated Controllers: Controllers resolve from their originating module's DI container
- 🎯 Auto-Prefixing: Module names automatically become URL prefixes (
UserModule
→/user/*
) - 🧩 Composable Middleware: Module-level and route-level middleware stacking
- ⚡ Zero Configuration: Automatic route discovery with convention-based patterns
- 🛡️ Type-Safe: Full PHP 8.4+ type system integration with enums and strict typing
Quick Start
composer require power-modules/router
<?php use Modular\Framework\App\ModularAppBuilder; use Modular\Router\RouterModule; use Modular\Router\PowerModule\Setup\RoutingSetup; $app = new ModularAppBuilder(__DIR__) ->withPowerSetup(new RoutingSetup()) ->withModules( RouterModule::class, // Provides routing infrastructure \MyApp\User\UserModule::class, // Your modules with routes \MyApp\Admin\AdminModule::class, ) ->build(); // Get router and handle PSR-7 requests $router = $app->get(\Modular\Router\Contract\ModularRouterInterface::class); $response = $router->handle($serverRequest);
📚 Documentation
Guide | Description |
---|---|
Getting Started | Build your first routed module in 5 minutes |
Architecture | Module boundaries, container hierarchy, and request lifecycle |
Use Cases | Web APIs, admin panels, plugin systems, and microservices |
API Reference | Complete interface and class documentation |
Advanced Patterns | Custom strategies, response decorators, and optimization |
Real-World Examples
Simple Module with Routes
<?php use Modular\Framework\PowerModule\Contract\PowerModule; use Modular\Framework\Container\ConfigurableContainerInterface; use Modular\Router\Contract\HasRoutes; use Modular\Router\Route; class UserModule implements PowerModule, HasRoutes { public function getRoutes(): array { return [ Route::get('/profile', UserController::class, 'show'), Route::put('/profile', UserController::class, 'update'), Route::post('/avatar', UserController::class, 'uploadAvatar') ->addMiddleware(AuthMiddleware::class), ]; } public function register(ConfigurableContainerInterface $container): void { $container->set(UserController::class, UserController::class) ->addArguments([UserService::class, LoggerInterface::class]); } } // Results in: /user/profile, /user/avatar
Module with Custom Prefix
<?php use Modular\Router\Contract\HasCustomRouteSlug; class ApiV1Module implements PowerModule, HasRoutes, HasCustomRouteSlug { public function getRouteSlug(): string { return '/api/v1'; } public function getRoutes(): array { return [ Route::get('/users', ApiUserController::class, 'index'), Route::post('/users', ApiUserController::class, 'create'), Route::get('/health', HealthController::class), ]; } } // Results in: /api/v1/users, /api/v1/health
Module with Middleware Stack
<?php use Modular\Router\Contract\HasMiddleware; class AdminModule implements PowerModule, HasRoutes, HasMiddleware { public function getMiddleware(): array { return [ AuthMiddleware::class, // All admin routes require auth AdminMiddleware::class, // All admin routes require admin role AuditMiddleware::class, // Log all admin actions ]; } public function getRoutes(): array { return [ Route::get('/dashboard', AdminController::class, 'dashboard'), Route::delete('/users/{id}', AdminController::class, 'deleteUser') ->addMiddleware(ConfirmationMiddleware::class), // Extra confirmation ]; } } // Middleware order: Auth → Admin → Audit → [Confirmation] → Controller
🏗️ Architecture Highlights
Module Encapsulation
- Route Ownership: Each module defines its own routes via
HasRoutes
- Controller Resolution: Controllers are resolved from their originating module's container
- Dependency Isolation: Module dependencies stay within module boundaries
Automatic Discovery
- Convention-Based:
UserModule
automatically gets/user/*
prefix - Zero Config: Routes are discovered and registered automatically during app build
- Override Ready: Implement
HasCustomRouteSlug
for custom prefixes
Middleware Composition
- Module-Level: Applied to all routes in the module
- Route-Level: Applied to specific routes only
- Resolution Priority: Module container first, then router container
🚀 Features
Route Definition
// HTTP method factories with intuitive API Route::get('/users', UserController::class, 'index'); Route::post('/users', UserController::class, 'create'); Route::put('/users/{id}', UserController::class, 'update'); Route::delete('/users/{id}', UserController::class, 'delete'); // Method defaults to 'handle' if not specified Route::get('/health', HealthController::class); // Fluent middleware chaining Route::post('/orders', OrderController::class) ->addMiddleware(AuthMiddleware::class, ValidationMiddleware::class);
Response Decorators
// Add global response transformations $router->addResponseDecorator(function (ResponseInterface $response): ResponseInterface { return $response ->withHeader('X-API-Version', '1.0') ->withHeader('X-Powered-By', 'Power-Modules'); });
Configuration System
// config/modular_router.php <?php use League\Route\Strategy\JsonStrategy; use Laminas\Diactoros\ResponseFactory; use Modular\Router\Config\Config; use Modular\Router\Config\Setting; return Config::create() ->set(Setting::Strategy, new JsonStrategy(new ResponseFactory()));
🛠️ Development
Build Commands
make test # Run PHPUnit tests make codestyle # Check PHP CS Fixer compliance make phpstan # Run PHPStan static analysis (level 8) make devcontainer # Build Docker development container
Code Standards
- Strict Types:
declare(strict_types=1);
on every file - PSR-12: Code style with additional rules (trailing commas, ordered imports)
- PHPStan Level 8: Maximum static analysis coverage
- PHP 8.4+: Latest language features and type system
🔌 Integration
Framework Dependencies
- Power Modules Framework: Core module system and DI container
- League/Route: Underlying routing engine (wrapped, not extended)
- PSR-7/PSR-15: HTTP message and middleware interfaces
Extension Points
- Custom Strategies: Replace default request/response handling
- Response Decorators: Global response transformations
- Middleware Stacks: Composable request/response processing
- Route Prefixes: Custom URL organization patterns
📊 Use Cases
- 🌐 Web APIs: RESTful APIs with module-organized endpoints
- 🏢 Admin Panels: Admin interfaces with role-based middleware
- 🔌 Plugin Systems: Third-party module integration
- 🚀 Microservices: Service-oriented architectures
- 📱 Mobile Backends: API backends for mobile applications
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
MIT License. See LICENSE for details.