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 Foundation Laravel Package

alexandrebulete/ddd-foundation

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Architectural Evolution: Transition from procedural or anemic domain models to a rich DDD architecture, enabling better scalability for complex business domains (e.g., e-commerce, SaaS platforms, or financial systems).
  • Bounded Context Adoption: Structurally enforce bounded contexts to isolate domain logic, reducing merge conflicts and enabling independent team ownership of features (e.g., "Order Processing" vs. "Inventory Management").
  • Domain-Driven Prioritization: Shift focus from infrastructure concerns (e.g., database schemas, APIs) to business value, aligning development with stakeholder priorities (e.g., "How does this support our subscription model?").
  • Build vs. Buy: Avoid reinventing DDD infrastructure (e.g., repositories, value objects, event handling) while maintaining flexibility to extend or replace components (e.g., swapping InMemoryRepository for Doctrine later).
  • Use Cases:
    • Greenfield Projects: Launch with DDD from day one (e.g., a new SaaS platform).
    • Legacy Refactoring: Gradually introduce DDD to modularize monolithic Laravel apps (e.g., extracting "Billing" into a bounded context).
    • Microservices Readiness: Prepare for decomposition by encapsulating domain logic in reusable modules.
    • Regulatory Compliance: Model business rules explicitly (e.g., GDPR data handling, financial auditing) to ensure traceability.

When to Consider This Package

  • Adopt if:

    • Your project has complex business rules that require explicit modeling (e.g., workflows, validation logic, or domain-specific calculations).
    • Your team is investing in long-term maintainability and willing to upskill in DDD (expect 3–6 months of ramp-up).
    • You’re building a modular monolith or microservices and need to decouple domain logic from infrastructure.
    • You’re using Laravel and want to avoid framework-specific DDD solutions (e.g., Symfony bundles) while keeping PHP-native flexibility.
    • You need reusable abstractions for:
      • Value Objects (e.g., Email, Money, UUID).
      • Repositories (e.g., UserRepository with pagination, filtering).
      • CQRS-like patterns (Commands/Queries/Handlers) without full CQRS frameworks.
      • Domain Events (e.g., OrderCreated, PaymentFailed).
    • You’re integrating with API Platform, Sylius, or Doctrine later (bridges are available).
  • Avoid if:

    • Your project is CRUD-heavy with minimal domain logic (e.g., a blog with posts/comments). Overhead isn’t justified.
    • Your team lacks PHP/Laravel experience or DDD familiarity. Consider starting with simpler architectures (e.g., Clean Architecture) first.
    • You need real-time event sourcing or advanced CQRS (e.g., event versioning, projections). This package focuses on foundational DDD, not these patterns.
    • You’re constrained by performance-critical paths (e.g., high-frequency trading). DDD abstractions add latency.
    • You’re using non-PHP stacks (e.g., Node.js, Python) or alternative Laravel DDD tools (e.g., spatie/laravel-ddd).
  • Look Elsewhere if:

    • You need enterprise-grade DDD tools: Evaluate Axon Framework (PHP), EventSauce, or custom solutions for large-scale systems.
    • You’re locked into Symfony and prefer its ecosystem (e.g., symfony/ux-dropzone, api-platform).
    • You require graphQL-native DDD (e.g., rebornix/laravel-ddd or spatie/laravel-query-builder).
    • Your domain is data-intensive (e.g., analytics, real-time dashboards). Consider ELT pipelines or data mesh approaches.

How to Pitch It (Stakeholders)

For Executives (Business/Strategy)

*"This package helps us build software that adapts to business needs—not the other way around. Right now, our codebase might look like a ‘digital photocopy’ of our business processes, but as we grow, that rigidity will slow us down. With Domain-Driven Design (DDD), we’ll:

  • Reduce technical debt by organizing code around business capabilities (e.g., ‘Subscriptions,’ ‘Payments’) instead of technical layers.
  • Future-proof our platform to handle changes like new regulations, market expansions, or feature requests without rewrites.
  • Improve collaboration between devs, product, and ops by speaking the same language (ubiquitous language) about how the business works. Think of it like upgrading from a spreadsheet to an ERP system—initially more complex, but it pays off when we scale. For a project like [X Initiative], this could save us 6–12 months of rework down the line. The trade-off? A 3–6 month learning curve for the team, but the ROI is clear."

Ask for:

  • Budget for team training (DDD workshops, books like Domain-Driven Design by Eric Evans).
  • Approval to pilot DDD in one bounded context (e.g., "Orders") before full adoption.

For Engineering Leaders (Architecture/Tech Debt)

*"This package gives us a scalable, Laravel-native foundation for DDD, which is critical for projects like [X] where:

  • Complexity is growing (e.g., workflows, multi-tenant logic, compliance rules).
  • Team turnover risks losing institutional knowledge of the domain.
  • Legacy code is becoming a bottleneck for new features.

Key Benefits:

  1. Separation of Concerns:

    • Domain Layer: Pure business logic (e.g., Order calculates taxes, validates rules).
    • Application Layer: Use cases (e.g., PlaceOrderCommand).
    • Infrastructure Layer: Laravel/Eloquent/Events (e.g., OrderRepository). No more ‘anemic domain models’ where behavior is scattered across services.
  2. Reusable Abstractions:

    • Value Objects: Strongly typed Email, Money, UUID (no more string fields with hidden validation).
    • Repositories: Standardized interfaces for find(), save(), search() (e.g., UserRepository instead of User::query()).
    • Commands/Queries: Clean separation for write vs. read operations (e.g., CreateUserCommand vs. GetUserQuery).
  3. Future-Proofing:

    • Microservices-ready: Bounded contexts can become independent services later.
    • Testability: Domain logic is unit-testable without databases (e.g., test Order rules with InMemoryRepository).
    • Extensible: Swap out InMemoryRepository for Doctrine or API Platform later.

Trade-offs:

  • Initial Complexity: Expect 20–30% more boilerplate for new features (e.g., defining User as an entity with invariants).
  • Team Upskill: Need to learn DDD concepts (e.g., Aggregate Roots, Domain Events). Propose a 2-day workshop to align the team.

Recommendation: Start with a pilot bounded context (e.g., ‘Orders’) to validate the approach before full adoption. If successful, we can gradually refactor other domains (e.g., ‘Users’, ‘Payments’)."*


For Developers (Implementation)

*"This package lets us write code that’s closer to the business problem, not just database operations. Here’s how it changes our workflow:

Before (Anemic Domain Model):

// User.php (just a data bag)
class User {
    public $name;
    public $email;
}

// UserService.php (handles all logic)
class UserService {
    public function validateEmail(User $user) { ... }
    public function calculateAge(User $user) { ... }
}

After (DDD with ddd-foundation):

// User.php (rich domain model)
class User {
    private Email $email;
    private string $name;

    public function __construct(Email $email, string $name) {
        $this->email = $email;
        $this->name = $name;
    }

    public function isEmailValid(): bool {
        return $this->email->isValid();
    }
}

// UserRepository.php (standardized interface)
class UserRepository implements RepositoryInterface {
    public function findByEmail(Email $email): ?User { ... }
}

// CreateUserCommand.php (application layer)
readonly class CreateUserCommand implements CommandInterface {
    public function __construct(
        public string $name,
        public string $email,
    ) {}
}

// CreateUserHandler.php (handles the command)
#[AsCommandHandler]
class CreateUserHandler {
    public function __invoke(CreateUserCommand $command) {
        $user = new User(
            Email::fromString($command->email),
            $command->name,
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
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
spatie/mailcoach-vapor