dbrekelmans/domain-driven-bundle
Install the Package Add the bundle via Composer in your Laravel project (note: this package is Symfony-focused, but can be used alongside Laravel via Symfony components or bridges):
composer require dbrekelmans/domain-driven-bundle
Configure the Bundle
Create a config/packages/domain_driven.yaml file in your Laravel project (or adapt your existing Symfony config if using both frameworks). Use the default structure:
domain_driven:
directories:
context: '%kernel.project_dir%/src'
application: 'Application'
domain: 'Domain'
infrastructure: 'Infrastructure'
presentation: 'Presentation'
config: 'config'
files:
routes: 'routes'
services: 'services'
Enable Routing
Add the following to your config/routes.yaml (Symfony) or adapt for Laravel’s routing system (e.g., via a bridge like spatie/laravel-symfony-support):
framework:
resource: '@DomainDrivenBundle/Resources/config/routes.yaml'
Create a Domain Context
Manually create a directory structure under src/ following the bundle’s conventions:
src/
└── YourDomain/
├── Application/
├── Domain/
│ ├── Entity/
│ ├── Event/
│ ├── Repository/
│ └── ...
├── Infrastructure/
│ └── config/
│ ├── routes.yaml
│ └── services.yaml
└── Presentation/
Define a Route or Service
Example routes.yaml in Infrastructure/config/routes.yaml:
your_domain_homepage:
path: /home
controller: YourDomain\Presentation\Controller\HomeController::index
Test the Integration Run your Symfony or Laravel application and verify the route/controller works. For Laravel, ensure you’ve bridged Symfony’s routing system (e.g., via a custom service provider or bridge package).
Domain-Centric Development
src/User/, src/Order/). Each context follows the same Application/Domain/Infrastructure/Presentation structure.src/User/Domain/Entity/User.php.src/User/Domain/Factory/UserFactory.php.src/User/Infrastructure/config/services.yaml:
services:
User\Infrastructure\Repository\UserRepository:
arguments:
- '@doctrine.orm.entity_manager'
src/User/Infrastructure/config/routes.yaml:
user_profile:
path: /user/{id}
controller: User\Presentation\Controller\UserController::show
Service Configuration
services.yaml/services.xml from Infrastructure/config/. Avoid manual services.yaml in config/ for domain-specific services.spatie/laravel-symfony-support):
// In a Laravel service provider
$this->app->singleton(
User\Domain\Service\UserService::class,
fn($app) => new User\Domain\Service\UserService(
$app->make(User\Infrastructure\Repository\UserRepository::class)
)
);
Routing Integration
spatie/laravel-symfony-support:
// config/app.php
'providers' => [
Spatie\SymfonySupport\SymfonySupportServiceProvider::class,
],
Then configure the bundle to expose routes to Laravel’s router.Presentation Layer
Presentation/Controller/. Example:
// src/User/Presentation/Controller/UserController.php
namespace User\Presentation\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class UserController extends AbstractController {
public function show(int $id): Response {
return new Response('User ID: ' . $id);
}
}
Presentation/Resources/views/ (if using Twig in Laravel via symfony/twig-bundle).Domain Events
Domain/Event/ and listen in Application/:
// src/User/Domain/Event/UserRegistered.php
class UserRegistered extends DomainEvent {}
// src/User/Application/Listener/UserRegisteredListener.php
class UserRegisteredListener {
public function __invoke(UserRegistered $event) {
// Handle event (e.g., send email)
}
}
services.yaml:
services:
User\Application\Listener\UserRegisteredListener:
tags:
- { name: kernel.event_listener, event: User\Domain\Event\UserRegistered }
Testing
Domain/ (e.g., entities, value objects).Infrastructure/.Presentation/.Laravel-Symfony Bridge
Use spatie/laravel-symfony-support to bridge Symfony components (e.g., DI, routing) into Laravel:
composer require spatie/laravel-symfony-support
Configure the bundle to work alongside Laravel’s service container.
Doctrine ORM
If using Doctrine in Laravel (via laravel-doctrine), place repositories in Domain/Repository/ and configure them in services.yaml:
services:
User\Infrastructure\Repository\UserRepository:
arguments:
- '@doctrine.orm.entity_manager'
tags:
- { name: doctrine.repository_service }
Custom Directories
Override default directories in config/packages/domain_driven.yaml:
domain_driven:
directories:
domain: 'Core' # Use 'Core' instead of 'Domain'
infrastructure: 'Backend'
Excluding Contexts Disable auto-loading for specific contexts by excluding them in config or via a custom loader.
Legacy Code Gradually migrate legacy code to the domain structure. Use the bundle’s auto-loading selectively for new features.
Symfony Dependency
symfony/framework-bundle). If your Laravel project doesn’t use Symfony, you’ll need to:
symfony/http-foundation).spatie/laravel-symfony-support to integrate Symfony’s DI/routing into Laravel.Routing Conflicts
spatie/laravel-symfony-support or a custom router).routes.yaml file exists in Infrastructure/config/.config/packages/domain_driven.yaml.Service Container Conflicts
spatie/laravel-symfony-support to merge them:
// config/app.php
'providers' => [
Spatie\SymfonySupport\SymfonySupportServiceProvider::class,
],
symfony. to avoid conflicts:
services:
symfony.user_repository:
class: User\Infrastructure\Repository\UserRepository
Outdated Package
Twig Integration
symfony/twig-bundle, but Laravel’s Blade templating may conflict. Options:
Namespace Collisions
User and `AdminHow can I help you explore Laravel packages today?