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.
Installation
composer require aljerom/symfony-boilerplate
Add the bundle to config/bundles.php:
return [
// ...
Aljerom\SymfonyBoilerplate\SymfonyBoilerplateBundle::class => ['all' => true],
];
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());
First Use Case: Domain Event Define an event:
namespace App\Event;
class UserCreatedEvent {}
Dispatch via DomainEventBus:
$this->domainEventBus->dispatch(new UserCreatedEvent());
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());
}
CommandBus for write operations, QueryBus for reads.public function __construct(
private CommandBus $commandBus,
private QueryBus $queryBus
) {}
CommandBus/QueryBus config:
# config/packages/aljerom_symfony_boilerplate.yaml
aljerom_symfony_boilerplate:
command_bus:
middleware: [validation, logging]
$this->domainEventBus->dispatch(new UserCreatedEvent($userId));
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)
}
}
services.yaml:
services:
App\Subscriber\UserCreatedSubscriber:
tags: [aljerom_symfony_boilerplate.domain_event_subscriber]
@RequestResolver to map HTTP requests to commands/queries:
#[RequestResolver]
public function createUser(Request $request, CommandBus $bus)
{
$bus->dispatch(new CreateUserCommand($request->request->all()));
}
RequestResolver to add validation or mapping logic.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
}
}
services.yaml:
services:
App\Subscriber\MyHttpSubscriber:
tags: [kernel.event_subscriber]
DomainEventBus to publish events from aggregates:
class UserAggregate
{
public function register()
{
$this->apply(new UserRegisteredEvent($this->id));
}
}
config/bundles.php (Symfony 4.3+).aljerom_symfony_boilerplate namespace in config/packages/aljerom_symfony_boilerplate.yaml:
aljerom_symfony_boilerplate:
command_bus:
middleware: [App\Middleware\ValidateCommand]
#[Autowire] or services.yaml tags).debug:container to verify buses are autowired:
php bin/console debug:container CommandBus
subscribedTo() or missing tags.php bin/console debug:container --tag=aljerom_symfony_boilerplate.request_resolver
CommandBus/QueryBus to add domain-specific logic:
class MyCommandBus extends CommandBus
{
public function dispatch($command)
{
// Pre-dispatch logic
parent::dispatch($command);
}
}
namespace App\Middleware;
use Aljerom\SymfonyBoilerplate\Bus\Middleware;
class ValidateCommand implements Middleware
{
public function handle($command, callable $next)
{
// Validation logic
return $next($command);
}
}
EventDispatcher for non-DDD events alongside domain events.$bus = $this->createMock(CommandBus::class);
$bus->expects($this->once())->method('dispatch');
$this->domainEventBus->dispatch(new UserCreatedEvent($userId));
$this->domainEventBus->flush(); // If supported
aljerom_symfony_boilerplate:
domain_event_bus:
transport: 'sync' # or 'async' with Messenger
How can I help you explore Laravel packages today?