PHPackages                             geekcell/ddd-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. geekcell/ddd-bundle

AbandonedArchivedSymfony-bundle[Framework](/categories/framework)

geekcell/ddd-bundle
===================

A bundle for pragmatic domain driven design in Symfony.

1.4.3(1y ago)1310.2k1[4 issues](https://github.com/geekcell/ddd-symfony-bundle/issues)MITPHPCI passing

Since Jan 16Pushed 1y ago5 watchersCompare

[ Source](https://github.com/geekcell/ddd-symfony-bundle)[ Packagist](https://packagist.org/packages/geekcell/ddd-bundle)[ RSS](/packages/geekcell-ddd-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (19)Versions (17)Used By (0)

Symfony Bundle for DDD
======================

[](#symfony-bundle-for-ddd)

This Symfony bundle augments [geekcell/php-ddd](https://github.com/geekcell/php-ddd) with framework-specific implementations to enable seamless [domain driven design](https://martinfowler.com/tags/domain%20driven%20design.html) in a familiar environment.

---

- [Installation](#installation)
- [Generator Commands](#generator-commands)
- [Building Blocks](#building-blocks)
    - [Model &amp; Repository](#model--repository)
    - [AggregateRoot &amp; Domain Events](#aggregateroot--domain-events)
    - [Command &amp; Query](#command--query)
    - [Controller](#controller)
    - [Resource](#resource)

Installation
------------

[](#installation)

To use this bundle, require it in Composer

```
composer require geekcell/ddd-bundle
```

Generator Commands
------------------

[](#generator-commands)

This bundle adds several [MakerBundle](https://symfony.com/bundles/SymfonyMakerBundle/current/index.html) commands to generate commonly used components.

In order to use them in your Symfony project, you need to require it with composer first

```
composer require symfony/maker-bundle
```

### Available Commands

[](#available-commands)

```
  make:ddd:command            Creates a new command class and handler
  make:ddd:controller         Creates a new controller class
  make:ddd:model              Creates a new domain model class
  make:ddd:query              Creates a new query class and handler
  make:ddd:resource           Creates a new API Platform resource
```

Building Blocks
---------------

[](#building-blocks)

### Model &amp; Repository

[](#model--repository)

The **domain model** is a representation of the domain concepts and business logic within your project. The **repository** on the other hand is an abstraction layer that provides a way to access and manipulate domain objects without exposing the details of the underlying data persistence mechanism (such as a database or file system).

Since Doctrine is the de-facto persistence layer for Symfony, this bundle also provides an (opinionated) implementation for a Doctrine-based repository.

#### Generator Command(s)

[](#generator-commands-1)

This command can be used to generate:

- The domain model class.
- A repository class for the model.
- The model's identity class as value object (optional).
- A Doctrine database entity configuration, either as annotation or separate config file (optional).
- A custom Doctrine type for the model's identity class (optional).

```
Description:
  Creates a new domain model class

Usage:
  make:ddd:model [options] [--] []

Arguments:
  name                               The name of the model class (e.g. Customer)

Options:
      --aggregate-root               Marks the model as aggregate root
      --entity=ENTITY                Use this model as Doctrine entity
      --with-identity=WITH-IDENTITY  Whether an identity value object should be created
      --with-suffix                  Adds the suffix "Model" to the model class name
```

### AggregateRoot &amp; Domain Events

[](#aggregateroot--domain-events)

Optionally, by inheriting from `AggregateRoot`, you can make a model class an **aggregate root**, which is used to encapsulate a group of related objects, along with the behavior and rules that apply to them. The aggregate root is usually responsible for managing the lifecycle of the objects within the aggregate, and for coordinating any interactions between them.

The `AggregateRoot` base class comes with some useful functionality to record and dispatch **domain events**, which represent significant occurrences or state changes within the domain of a software system.

#### Generator Command(s)

[](#generator-commands-2)

N/A

#### Example Usage

[](#example-usage)

```
// src/Domain/Event/OrderPlacedEvent.php

use GeekCell\Ddd\Contracts\Domain\Event as DomainEvent;

readonly class OrderPlacedEvent implements DomainEvent
{
    public function __construct(
        public Order $order,
    ) {
    }
}

// src/Domain/Model/Order.php

use GeekCell\DddBundle\Domain\AggregateRoot;

class Order extends AggregateRoot
{
    public function save(): void
    {
        $this->record(new OrderPlacedEvent($this));
    }

    // ...
}

// Actual usage ...

$order = new Order( /* ... */ );
$order->save();
$order->commit(); // All recorded events will be dispatched and released
```

*Hint: If you want to dispatch an event directly, use `AggregateRoot::dispatch()` instead of `AggregateRoot::record()`.*

If you cannot (or don't want to) extend from `AggregateRoot`, you can alternative use `DispatchableTrait` to add dispatching capabilities to any class. The former is however the recommended way.

### Command &amp; Query

[](#command--query)

You can use `CommandBus` and `QueryBus` as services to implement [CQRS](https://martinfowler.com/bliki/CQRS.html). Internally, both buses will use the [Symfony messenger](https://symfony.com/doc/current/messenger.html) to dispatch commands and queries.

#### Generator Command(s)

[](#generator-commands-3)

These commands can be used to generate:

- A command and command handler class.
- A query and query handler class.

The query / command generated is just an empty class. The handler class is registered as a message handler for the configured [Symfony Messenger](https://symfony.com/doc/current/messenger.html).

```
Description:
  Creates a new query|command class and handler

Usage:
  make:ddd:query|command []

Arguments:
  name                     The name of the query|command class (e.g. Customer)
```

#### Example Usage

[](#example-usage-1)

```
// src/Application/Query/TopRatedBookQuery.php

use GeekCell\Ddd\Contracts\Application\Query;

readonly class TopRatedBooksQuery implements Query
{
    public function __construct(
        public string $category,
        public int $sinceDays,
        public int $limit = 10,
    ) {
    }

    // Getters etc.
}

// src/Application/Query/TopRatedBookQueryHandler.php

use GeekCell\Ddd\Contracts\Application\QueryHandler;

#[AsMessageHandler]
class TopRatedBookQueryHandler implements QueryHandler
{
    public function __construct(
        private readonly BookRepository $repository,
    ) {
    }

    public function __invoke(TopRatedBookQuery $query)
    {
        $books = $this->repository
            ->findTopRated($query->category, $query->sinceDays)
            ->paginate($query->limit);

        return $books;
    }
}

// src/Infrastructure/Http/Controller/BookController.php

use GeekCell\Ddd\Contracts\Application\QueryBus;

class BookController extends AbstractController
{
    public function __construct(
        private readonly QueryBus $queryBus,
    ) {
    }

    #[Route('/books/top-rated')]
    public function getTopRated(Request $request)
    {
        $query = new TopRatedBooksQuery( /* extract from request */ );
        $topRatedBooks = $this->queryBus->dispatch($query);

        // ...
    }
}
```

### Controller

[](#controller)

A standard Symfony controller, but augmented with command and query bus(es).

#### Generator Command

[](#generator-command)

This command can be used to generate a controller with optional `QueryBus` and `CommandBus` dependencies.

```
Description:
  Creates a new controller class

Usage:
  make:ddd:controller [options] [--] []

Arguments:
  name                       The name of the model class (e.g. Customer)

Options:
      --include-query-bus    Add a query bus dependency
      --include-command-bus  Add a command bus dependency
```

### Resource

[](#resource)

An [API Platform](https://api-platform.com/) resource, but instead of using the standard approach of using a combined entity/resource approach, it is preferred to separate model (domain layer) and API Platform specific resource (infrastructure layer)

#### Generator Command

[](#generator-command-1)

Minimum required API Platform version is [2.7](https://api-platform.com/docs/core/upgrade-guide/#api-platform-2730) for the [new metadata system](https://api-platform.com/docs/core/upgrade-guide/#apiresource-metadata).

```
Description:
  Creates a new API Platform resource

Usage:
  make:ddd:resource [options] [--] []

Arguments:
  name            The name of the model class to create the resource for (e.g. Customer). Model must exist already.

Options:
      --config    Config flavor to create (attribute|xml).
```

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance38

Infrequent updates — may be unmaintained

Popularity26

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~59 days

Recently: every ~167 days

Total

14

Last Release

445d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/898471698110cef7b7a749859f26a7e180f2eff02d23765962bbb34d4ad11492?d=identicon)[geekcell](/maintainers/geekcell)

---

Top Contributors

[![b00gizm](https://avatars.githubusercontent.com/u/59077?v=4)](https://github.com/b00gizm "b00gizm (30 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (19 commits)")[![janvt](https://avatars.githubusercontent.com/u/3647057?v=4)](https://github.com/janvt "janvt (14 commits)")[![Bl00D4NGEL](https://avatars.githubusercontent.com/u/17341310?v=4)](https://github.com/Bl00D4NGEL "Bl00D4NGEL (2 commits)")

---

Tags

dddddd-patternsdomain-driven-designphpsymfonysymfony-bundle

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/geekcell-ddd-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/geekcell-ddd-bundle/health.svg)](https://phpackages.com/packages/geekcell-ddd-bundle)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[contao/core-bundle

Contao Open Source CMS

1231.6M2.4k](/packages/contao-core-bundle)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k16.7M310](/packages/easycorp-easyadmin-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
