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

Symfony Boilerplate Laravel Package

aljerom/symfony-boilerplate

A lightweight Symfony boilerplate to kickstart new projects with a ready-to-use structure, common configuration, and sensible defaults. Helps you bootstrap development faster and keep your app setup consistent across environments.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require aljerom/symfony-boilerplate
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        Aljerom\SymfonyBoilerplate\SymfonyBoilerplateBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Command Bus Define a command:

    namespace App\Command;
    
    class CreateUserCommand {}
    

    Create a handler:

    namespace App\Command\Handler;
    
    use App\Command\CreateUserCommand;
    use Aljerom\SymfonyBoilerplate\Bus\CommandBus;
    
    class CreateUserCommandHandler
    {
        public function __invoke(CreateUserCommand $command)
        {
            // Business logic
        }
    }
    

    Dispatch via CommandBus (autowired):

    $this->commandBus->dispatch(new CreateUserCommand());
    
  3. First Use Case: Domain Event Define an event:

    namespace App\Event;
    
    class UserCreatedEvent {}
    

    Dispatch via DomainEventBus:

    $this->domainEventBus->dispatch(new UserCreatedEvent());
    
  4. First Use Case: Request Resolver Annotate a controller method:

    use Aljerom\SymfonyBoilerplate\RequestResolver\RequestResolver;
    
    #[RequestResolver]
    public function handle(Request $request, CommandBus $bus)
    {
        $bus->dispatch(new CreateUserCommand());
    }
    

Implementation Patterns

Command/Query Buses

  • Workflow: Use CommandBus for write operations, QueryBus for reads.
  • Integration: Autowire buses into services/controllers:
    public function __construct(
        private CommandBus $commandBus,
        private QueryBus $queryBus
    ) {}
    
  • Middleware: Add middleware via CommandBus/QueryBus config:
    # config/packages/aljerom_symfony_boilerplate.yaml
    aljerom_symfony_boilerplate:
        command_bus:
            middleware: [validation, logging]
    

Domain Events

  • Workflow:
    1. Dispatch events after domain logic:
      $this->domainEventBus->dispatch(new UserCreatedEvent($userId));
      
    2. Subscribe via DomainEventSubscriber:
      namespace App\Subscriber;
      
      use App\Event\UserCreatedEvent;
      use Aljerom\SymfonyBoilerplate\Bus\DomainEventSubscriber;
      
      class UserCreatedSubscriber implements DomainEventSubscriber
      {
          public static function subscribedTo(): string
          {
              return UserCreatedEvent::class;
          }
      
          public function handle(UserCreatedEvent $event)
          {
              // Side effects (e.g., notifications)
          }
      }
      
  • Integration: Register subscribers in services.yaml:
    services:
        App\Subscriber\UserCreatedSubscriber:
            tags: [aljerom_symfony_boilerplate.domain_event_subscriber]
    

Request Resolver

  • Pattern: Use @RequestResolver to map HTTP requests to commands/queries:
    #[RequestResolver]
    public function createUser(Request $request, CommandBus $bus)
    {
        $bus->dispatch(new CreateUserCommand($request->request->all()));
    }
    
  • Customization: Extend RequestResolver to add validation or mapping logic.

HTTP/Console Subscribers

  • Workflow:
    1. Subscribe to KernelEvents::CONTROLLER or ConsoleEvents::COMMAND:
      use Symfony\Component\HttpKernel\Event\ControllerEvent;
      use Aljerom\SymfonyBoilerplate\Subscriber\HttpSubscriber;
      
      class MyHttpSubscriber implements HttpSubscriber
      {
          public function onKernelController(ControllerEvent $event)
          {
              // Pre/post-controller logic
          }
      }
      
    2. Register in services.yaml:
      services:
          App\Subscriber\MyHttpSubscriber:
              tags: [kernel.event_subscriber]
      

DDD Integration

  • Aggregate Roots: Use DomainEventBus to publish events from aggregates:
    class UserAggregate
    {
        public function register()
        {
            $this->apply(new UserRegisteredEvent($this->id));
        }
    }
    
  • Repositories: Combine with Doctrine or custom repositories for persistence.

Gotchas and Tips

Configuration Quirks

  • Bundle Enablement: Ensure the bundle is enabled in config/bundles.php (Symfony 4.3+).
  • YAML Config: Use aljerom_symfony_boilerplate namespace in config/packages/aljerom_symfony_boilerplate.yaml:
    aljerom_symfony_boilerplate:
        command_bus:
            middleware: [App\Middleware\ValidateCommand]
    
  • Autowiring: Ensure handlers are autowired (e.g., #[Autowire] or services.yaml tags).

Debugging

  • Command/Query Dispatch: Use debug:container to verify buses are autowired:
    php bin/console debug:container CommandBus
    
  • Event Subscribers: Check for typos in subscribedTo() or missing tags.
  • Request Resolver: Validate annotations with:
    php bin/console debug:container --tag=aljerom_symfony_boilerplate.request_resolver
    

Extension Points

  • Custom Buses: Extend CommandBus/QueryBus to add domain-specific logic:
    class MyCommandBus extends CommandBus
    {
        public function dispatch($command)
        {
            // Pre-dispatch logic
            parent::dispatch($command);
        }
    }
    
  • Middleware: Create reusable middleware for validation, logging, or transactions:
    namespace App\Middleware;
    
    use Aljerom\SymfonyBoilerplate\Bus\Middleware;
    
    class ValidateCommand implements Middleware
    {
        public function handle($command, callable $next)
        {
            // Validation logic
            return $next($command);
        }
    }
    
  • Event Subscribers: Use EventDispatcher for non-DDD events alongside domain events.

Pitfalls

  • Circular Dependencies: Avoid circular references between commands/handlers.
  • Event Ordering: Domain events are dispatched synchronously; use async subscribers (e.g., Symfony Messenger) for long-running tasks.
  • Request Resolver Overhead: Annotate sparsely to avoid performance hits in high-traffic endpoints.
  • Middleware Stack: Ensure middleware is ordered correctly (e.g., validation before logging).

Tips

  • Testing: Mock buses in tests:
    $bus = $this->createMock(CommandBus::class);
    $bus->expects($this->once())->method('dispatch');
    
  • Performance: Batch domain events for bulk operations:
    $this->domainEventBus->dispatch(new UserCreatedEvent($userId));
    $this->domainEventBus->flush(); // If supported
    
  • Symfony Messenger: For async processing, integrate with Symfony Messenger:
    aljerom_symfony_boilerplate:
        domain_event_bus:
            transport: 'sync' # or 'async' with Messenger
    
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime