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

This package is auto-updated.

Last update: 2025-09-22 22:23:30 UTC


README

CI Packagist Version PHP Version License: MIT PHPStan

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.