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

Ddd Core Laravel Package

becklyn/ddd-core

DDD/CQRS/event-sourcing core building blocks for PHP: entity identities, domain events, command handling, transactions, and an event store workflow. Framework-agnostic abstractions with Symfony/Doctrine/SimpleBus bridge packages available.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strengths:

    • DDD/CQRS/Event Sourcing Alignment: The package enforces ubiquitous language, bounded contexts, and aggregate roots, making it ideal for complex domains (e.g., financial systems, supply chains).
    • Framework-Agnostic Core: Abstract interfaces (CommandBus, EventStore, TransactionManager) allow integration with any stack (Laravel, Symfony, or custom implementations).
    • Eventual Consistency: The "core transaction loop" ensures reliable event propagation and compensating actions for sagas, critical for distributed workflows.
    • Auditability: Event sourcing provides immutable logs, addressing compliance needs (e.g., fintech, healthcare).
    • Modularity: Aggregates and domain services encapsulate logic, easing future microservice decomposition.
  • Weaknesses:

    • Steep Learning Curve: Requires deep DDD knowledge (e.g., aggregate design, event storming) and PHP OOP expertise (traits, interfaces, dependency injection).
    • Performance Overhead: Event sourcing and CQRS introduce latency for reads (requires projections) and complexity in transaction management.
    • Lack of Built-in Caching: No native support for read models or query optimization (must implement projections manually).
    • Symfony-Centric Bridges: While framework-agnostic, the provided bridges (Doctrine, SimpleBus) favor Symfony, which may require custom Laravel adapters.

Integration Feasibility

  • Laravel Compatibility:

    • Command Bus: Laravel’s console commands or HTTP controllers can dispatch commands, but message correlation (v4.0.0+) may need custom middleware.
    • Event Bus: Laravel’s events/listeners can integrate with EventBus, but SimpleBus (Symfony’s default) would require a Laravel-compatible alternative (e.g., spatie/laravel-simple-bus).
    • Transaction Management: Laravel’s database transactions can wrap TransactionManager, but distributed transactions (e.g., across services) would need Saga orchestration (e.g., camspiers/laravel-queue-sagas).
    • Event Store: No native Laravel support; would need Doctrine DBAL, Elasticsearch, or custom storage (e.g., DynamoDB).
    • Identity Management: Laravel’s model keys can map to AggregateId, but UUIDs (recommended) may conflict with Laravel’s default incrementing IDs.
  • Key Integration Points:

    Component Laravel Equivalent Customization Required
    Command Bus HTTP routes / Artisan commands Middleware for correlation IDs
    Event Bus Laravel Events Replace SimpleBus with Laravel-compatible pub/sub
    Transaction Manager DB Transactions Wrap in TransactionManager
    Event Store Custom (DB/NoSQL) Implement EventStore interface
    Aggregate Repository Eloquent Repositories Extend AggregateRepository trait

Technical Risk

  • High Risks:

    • Eventual Consistency Complexity: Debugging stale reads or failed event processing requires distributed tracing (e.g., OpenTelemetry).
    • Transaction Boundaries: Laravel’s implicit transactions (e.g., in controllers) may conflict with TransactionManager’s explicit rollback/commit.
    • Performance Bottlenecks: Event sourcing reads (replaying events) can be slow; projections must be optimized (e.g., materialized views).
    • Testing Overhead: BDD-style testing (given/when/then) with Prophecy may not align with Laravel’s PHPUnit conventions.
    • Vendor Lock-in: While framework-agnostic, Symfony bridges may influence long-term architecture decisions.
  • Mitigation Strategies:

    • Start Small: Pilot with one aggregate (e.g., Order) before full adoption.
    • Hybrid Approach: Use Eloquent for simple entities and becklyn/ddd-core for complex aggregates.
    • Custom Adapters: Build Laravel-specific implementations for missing components (e.g., EventStore).
    • Monitoring: Instrument event processing latency and transaction failures early.
    • Documentation: Create internal DDD guidelines to onboard developers.

Key Questions for Stakeholders

  1. Domain Complexity:
    • "Are we solving a problem where business rules are intertwined with infrastructure (e.g., database operations), or is this overkill for our current needs?"
  2. Team Expertise:
    • "Does the team have experience with DDD, event sourcing, or CQRS? If not, what’s the training/ramp-up plan?"
  3. Compliance Requirements:
    • "Do we need immutable audit logs for regulatory purposes? If not, is event sourcing worth the complexity?"
  4. Performance Tradeoffs:
    • "Can we tolerate higher read latency for eventual consistency, or do we need strong consistency for some queries?"
  5. Long-Term Architecture:
    • "Are we planning to decompose into microservices? If so, how will aggregate boundaries align with service boundaries?"
  6. Tooling Support:
    • "Are we willing to build custom Laravel adapters for missing components (e.g., event store), or should we stick to Symfony bridges?"
  7. Testing Strategy:
    • "How will we test eventual consistency scenarios? Will we use time-travel testing (replaying events)?"
  8. Rollback Strategy:
    • "How will we handle failed sagas? Do we need compensating transactions or manual intervention?"

Integration Approach

Stack Fit

  • Laravel-Specific Considerations:

    • Command Handling:
      • Use Laravel’s HTTP routes or Artisan commands to dispatch commands via CommandBus.
      • Example:
        Route::post('/orders/{id}/cancel', function (CancelOrderCommand $command) {
            $commandBus->dispatch($command);
            return response()->json(['status' => 'queued']);
        });
        
      • Correlation IDs: Add middleware to inject X-Correlation-ID headers into commands.
    • Event Handling:
      • Replace Symfony’s SimpleBus with Laravel Events or a message queue (e.g., Redis, RabbitMQ).
      • Example:
        Event::listen(OrderCancelled::class, function (OrderCancelled $event) {
            // Dispatch to another service or update projections
        });
        
    • Transaction Management:
      • Wrap Laravel’s DB::transaction() in TransactionManager:
        DB::transaction(function () use ($command, $transactionManager) {
            $handler = new CancelOrderHandler($eventRegistry, $transactionManager);
            $handler->handleCommand($command);
        });
        
    • Event Store:
      • Options:
        1. Doctrine DBAL: Store events in a json column with EventStore interface.
        2. Elasticsearch: For fast event queries.
        3. Custom: Use Laravel’s filesystem or a NoSQL database (e.g., DynamoDB).
    • Aggregate Repositories:
      • Extend Laravel’s Eloquent repositories to implement AggregateRepository:
        class OrderRepository implements AggregateRepository {
            public function load(AggregateId $id): ?AggregateRoot {
                return Order::find($id->value());
            }
        }
        
  • Symfony vs. Laravel Tradeoffs:

    Feature Symfony Bridge Available Laravel Workaround Needed
    Command Bus Yes (SimpleBus) Custom middleware or queue-based dispatch
    Event Bus Yes (SimpleBus) Laravel Events or queue listener
    Transaction Manager Yes (Doctrine) Wrap Laravel DB transactions
    Event Store Yes (Doctrine) Custom implementation (DB/NoSQL)
    Testing Traits Yes Adapt PHPUnit/Prophecy to Laravel’s testing

Migration Path

  1. Phase 1: Proof of Concept (2-4 weeks)
    • Scope: Single aggregate (e.g., Order).
    • Tasks:
      • Implement Order as an aggregate with EventSourcedProviderCapabilities.
      • Create a CancelOrderCommand and handler.
      • Store events in a simple table (e.g., event_store with aggregate_id, event_type, payload).
      • Test with manual event replay (e.g., Order::replayEvents()).
    • Goal: Validate core loop and **event
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.
cadot.eu/make
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
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