- Can I use becklyn/ddd-core in Laravel without Symfony or Doctrine?
- Yes, the core package is framework-agnostic and provides interfaces for all components (CommandBus, EventStore, TransactionManager). You’ll need to implement Laravel-specific adapters (e.g., for event storage or transactions) or use third-party packages like `spatie/laravel-simple-bus` for command handling. The README emphasizes custom implementations for non-Symfony stacks.
- How do I integrate Laravel’s built-in events with becklyn/ddd-core’s event bus?
- Laravel’s event system can coexist with the core’s `EventBus`, but you’ll need to bridge them manually. For example, dispatch domain events via the `EventBus` and listen to them with Laravel’s `EventServiceProvider`. Replace SimpleBus (Symfony’s default) with a Laravel-compatible pub/sub solution like `spatie/laravel-simple-bus` for seamless integration.
- What’s the best way to handle transactions in Laravel with this package?
- Wrap Laravel’s database transactions around the `TransactionManager` to ensure atomicity. For distributed transactions (e.g., across services), use sagas with compensating actions (e.g., `camspiers/laravel-queue-sagas`). The core enforces a transaction loop, so avoid mixing implicit Laravel transactions (e.g., in controllers) with explicit `TransactionManager` commits to prevent conflicts.
- Does becklyn/ddd-core support event sourcing with Laravel’s Eloquent models?
- No, Eloquent models aren’t event-sourced by default. You’ll need to implement an `EventStore` (e.g., using Doctrine DBAL, Elasticsearch, or DynamoDB) and rebuild aggregates from events. The package provides abstractions for this, but projections (read models) must be manually optimized for performance, as event replay can be slow.
- How do I test aggregates and command handlers in Laravel’s PHPUnit environment?
- Use Prophecy or Laravel’s mocking tools to test aggregates and handlers in isolation. For event-driven workflows, verify event publishing and consumption with mock `EventBus` implementations. The package’s BDD-style testing (e.g., given/when/then) may require custom PHPUnit setups, especially for transaction rollback scenarios.
- What Laravel versions are officially supported by becklyn/ddd-core?
- The package itself has no Laravel-specific dependencies, but compatibility depends on your custom adapters. Test with Laravel 8+ (recommended for Symfony bridge alternatives) or 9/10 for newer features. Check the `becklyn/ddd-doctrine-bridge` or `becklyn/ddd-symfony-bridge` for Symfony version ties, as they may indirectly affect Laravel integrations.
- Is there a performance penalty for using event sourcing in production?
- Yes, event sourcing introduces latency for reads due to event replay and projections. Mitigate this by pre-building materialized views (e.g., with Laravel’s query caching or Redis). Write performance is also impacted by transaction management; optimize by batching events or using async event processing (e.g., Laravel queues). Benchmark with your domain’s event volume.
- Can I mix becklyn/ddd-core with Laravel’s built-in features like queues or notifications?
- Absolutely. Use Laravel queues to defer event processing or notifications triggered by domain events. For example, dispatch a `SendWelcomeEmail` command after an `UserRegistered` event. The core’s `EventBus` can integrate with Laravel’s `Bus` facade or queue listeners, but ensure idempotency for retries.
- What alternatives exist for DDD/CQRS in Laravel if becklyn/ddd-core feels too complex?
- Consider lighter alternatives like `spatie/laravel-commander` (for CQRS), `asgrim/laravel-event-sourcing` (event sourcing), or `nWidart/laravel-modules` (bounded contexts). For full DDD, `ddd-php/ddd` or `cuy-z/z-framework` offer Laravel-friendly abstractions with less steep learning curves. Evaluate based on your need for event sourcing or transactional integrity.
- How do I handle aggregate identity conflicts with Laravel’s auto-incrementing IDs?
- Use UUIDs for aggregate identities (recommended by the package) instead of Laravel’s default integer IDs. For existing projects, map Laravel’s primary keys to `AggregateId` via a custom `AggregateRepository`. Avoid conflicts by ensuring UUIDs are generated consistently (e.g., with `ramsey/uuid`) and stored as strings in the database.