Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rich Bundle Laravel Package

1tomany/rich-bundle

Symfony bundle implementing the RICH (Request, Input, Command, Handler) architecture. Encourages single-responsibility actions with explicit Input/Command/Handler classes for clear, safe, and futureproof backend development without heavy DDD/CQRS overhead.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Alignment with Laravel/PHP Ecosystem: The RICH Bundle is designed for Symfony, not Laravel, but its core principles (decoupled components, single responsibility, stateless handlers) align well with Laravel’s service container, middleware, and command-bus patterns. Laravel’s Laravel Framework (v10+) and Laravel Serialization packages could replace Symfony’s serializer/validator, while Laravel’s Artisan commands or Lumen’s request handling could mirror the Input/Command/Handler flow.
  • Domain-Driven Design (DDD) Lite: The bundle enforces modularity and separation of concerns, which is valuable for Laravel applications adopting DDD or microservices. The Contract layer mirrors Laravel’s interfaces/repositories pattern.
  • Asynchronous Readiness: The stateless Command/Handler design is compatible with Laravel’s Queues (e.g., dispatch()) or Laravel Horizon, enabling future async scaling without refactoring.

Integration Feasibility

  • Symfony Dependencies: The bundle relies on Symfony’s Serializer, Validator, and HttpFoundation. Laravel alternatives:
    • Validation: Replace with Laravel’s built-in Validator or FormRequest.
    • Serialization: Use Laravel\Serializable or spatie/array-to-object.
    • Request Handling: Adapt Input classes to Laravel’s FormRequest or Illuminate\Http\Request.
  • Doctrine ORM: The bundle assumes Doctrine. For Laravel, replace with Eloquent or Laravel Scout (for repositories). The RepositoryInterface pattern can be replicated with Laravel’s Repository pattern (e.g., spatie/laravel-repository).
  • Event System: Symfony’s event dispatcher can be replaced with Laravel’s Events or Laravel Echo (for real-time).

Technical Risk

  • Symfony-Specific Abstractions:
    • Risk: Attributes like #[SourceUser] or #[SourceIpAddress] are Symfony-specific. Mitigation: Create Laravel-specific attributes or middleware to map request data to Input objects.
    • Risk: Symfony’s Container vs. Laravel’s Service Provider. Mitigation: Use Laravel’s bindings or tagging to register handlers as services.
  • Performance Overhead:
    • Risk: Reflection-heavy attribute parsing (e.g., Source* attributes) may impact performance. Mitigation: Benchmark and optimize with Laravel’s macroable or custom trait-based mapping.
  • Learning Curve:
    • Risk: Team unfamiliarity with RICH principles may slow adoption. Mitigation: Provide Laravel-specific examples (e.g., CreateUserHandler in Laravel’s app/Commands directory).

Key Questions

  1. How will we map Symfony’s Input/Command flow to Laravel’s request lifecycle?
    • Example: Should Input classes extend FormRequest or use middleware to populate DTOs?
  2. What’s the migration path for existing Laravel controllers?
    • Should we refactor controllers to use Handler classes directly (e.g., via middleware)?
  3. How will we handle Laravel’s built-in features (e.g., Illuminate\Validation\Validator) vs. Symfony’s Validator?
    • Will we duplicate validation logic or create adapters?
  4. Asynchronous Support:
    • How will we integrate Handler classes with Laravel Queues? Will we use dispatch() or a custom command bus?
  5. Testing Strategy:
    • How will we test Handler classes in isolation (e.g., mocking repositories) in Laravel’s testing framework?

Integration Approach

Stack Fit

  • Core Laravel Components:
    • Request Handling: Replace Symfony’s Input with Laravel’s FormRequest or custom DTOs (e.g., spatie/data-transfer-object).
    • Validation: Use Laravel’s Validator or FormRequest rules instead of Symfony’s Assert constraints.
    • Dependency Injection: Leverage Laravel’s Service Container to bind Handler classes and RepositoryInterface implementations.
    • Routing: Map routes to Handler classes via middleware or controller adapters (e.g., HandleCreateAccount middleware).
  • Optional Add-ons:
    • Command Bus: Use laravel-softwarearchitects/command-bus for async Handler execution.
    • Event System: Replace Symfony events with Laravel’s Events or Laravel Echo.
    • Testing: Use Laravel’s Mockery or PestPHP to test Handler classes in isolation.

Migration Path

  1. Phase 1: Pilot Module
    • Select a non-critical module (e.g., User or Post) and refactor it using RICH principles in Laravel.
    • Example:
      • Replace a UserController with:
        • CreateUserInput (extends FormRequest).
        • CreateUserCommand (DTO).
        • CreateUserHandler (service class).
        • Middleware to dispatch the handler.
  2. Phase 2: Core Integration
    • Replace Symfony’s Serializer/Validator with Laravel equivalents.
    • Create a custom RichServiceProvider to bind Handler interfaces to implementations.
  3. Phase 3: Full Adoption
    • Gradually replace controllers with Handler-based middleware.
    • Integrate with Laravel Queues for async Handler execution.

Compatibility

  • Symfony → Laravel Mappings:
    Symfony Component Laravel Equivalent
    HttpFoundation\Request Illuminate\Http\Request
    Validator Illuminate\Validation\Validator
    Serializer spatie/array-to-object
    EventDispatcher Illuminate\Events\Dispatcher
    Container Illuminate\Container
  • Challenges:
    • Attributes: Laravel lacks Symfony’s attribute parsing. Use middleware or traits to replicate Source* behavior.
    • Doctrine: Replace with Eloquent or a repository pattern library.

Sequencing

  1. Step 1: Scaffold Module Structure
    • Create Laravel-specific directories (e.g., app/Modules/Account/Handlers, app/Modules/Account/Commands).
    • Example structure:
      app/
        Modules/
          Account/
            Actions/
              Commands/
                CreateAccountCommand.php
              Handlers/
                CreateAccountHandler.php
              Input/
                CreateAccountRequest.php (extends FormRequest)
            Contracts/
              Repository/
                AccountRepositoryInterface.php
      
  2. Step 2: Implement Input Layer
    • Convert Symfony Input classes to Laravel FormRequest or DTOs.
    • Example:
      // app/Modules/Account/Actions/Input/CreateAccountRequest.php
      namespace App\Modules\Account\Actions\Input;
      
      use Illuminate\Foundation\Http\FormRequest;
      use App\Modules\Account\Actions\Commands\CreateAccountCommand;
      
      class CreateAccountRequest extends FormRequest {
          public function rules(): array {
              return [
                  'name' => 'required|string|max:128',
                  'email' => 'required|email|max:128',
              ];
          }
      
          public function toCommand(): CreateAccountCommand {
              return new CreateAccountCommand(
                  $this->user()->id,
                  $this->name,
                  $this->email,
              );
          }
      }
      
  3. Step 3: Implement Handler Layer
    • Create stateless Handler classes with Laravel’s ServiceProvider bindings.
    • Example:
      // app/Modules/Account/Actions/Handlers/CreateAccountHandler.php
      namespace App\Modules\Account\Actions\Handlers;
      
      use App\Modules\Account\Actions\Commands\CreateAccountCommand;
      use App\Modules\Account\Contracts\Repository\AccountRepositoryInterface;
      
      class CreateAccountHandler {
          public function __construct(
              private AccountRepositoryInterface $repository
          ) {}
      
          public function handle(CreateAccountCommand $command) {
              $this->repository->create($command);
          }
      }
      
  4. Step 4: Wire Middleware/Routing
    • Use middleware to dispatch handlers from routes.
    • Example middleware:
      // app/Http/Middleware/DispatchHandler.php
      namespace App\Http\Middleware;
      
      use Closure;
      use App\Modules\Account\Actions\Handlers\CreateAccountHandler;
      
      class DispatchHandler {
          public function __invoke(CreateAccountHandler $handler, Closure $next) {
              $handler->handle($this->request->toCommand());
              return $next($request);
          }
      }
      
    • Route definition:
      Route::post('/accounts', CreateAccountRequest::class)
           ->middleware(DispatchHandler::class);
      
  5. Step 5: Test and Optimize
    • Write unit tests for Handler classes (mock repositories).
    • Profile performance and optimize attribute parsing (if used).

Operational Impact

Maintenance

  • Pros:
    • Decoupled Components: Changes to one Handler or Input class won’t ripple across
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor