Skip to content

Commit 7b44d3c

Browse files
authored
Update README.md
Signed-off-by: Pascal Cremer <pascal.cremer@geekcell.io>
1 parent 41a0c0d commit 7b44d3c

File tree

1 file changed

+100
-107
lines changed

1 file changed

+100
-107
lines changed

README.md

Lines changed: 100 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
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.
44

5+
---
6+
7+
- [Installation](#installation)
8+
- [Generator Commands](#generator-commands)
9+
- [Building Blocks](#building-blocks)
10+
- [Model & Repository](#model--repository)
11+
- [AggregateRoot & Domain Events](#aggregateroot--domain-events)
12+
- [Command & Query](#command--query)
13+
- [Controller](#controller)
14+
- [Resource](#resource)
15+
516
## Installation
617

718
To use this bundle, require it in Composer
@@ -10,18 +21,62 @@ To use this bundle, require it in Composer
1021
composer require geekcell/ddd-bundle
1122
```
1223

13-
## Quickstart
24+
## Generator Commands
25+
26+
This bundle adds several [MakerBundle](https://symfony.com/bundles/SymfonyMakerBundle/current/index.html) commands to generate commonly used components.
27+
28+
In order to use them in your Symfony project, you need to require it with composer first
29+
30+
```bash
31+
composer require symfony/maker-bundle
32+
```
33+
34+
## Building Blocks
1435

15-
- [Aggregate Root](#aggregate-root)
16-
- [Repositories](#repositories)
17-
- [Command & Query Bus](#command--query-bus)
18-
- [Supporting Tools](#supporting-tools)
36+
### Model & Repository
1937

20-
## Aggregate Root
38+
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).
2139

22-
Extend from `AggregateRoot` to record and commit domain events. Domain events must implement the (marker) interface `DomainEvent`. Events will be dispatched via the currently configured Symfony event dispatcher.
40+
Since Doctrine is the de-facto persistence layer for Symfony, this bundle also provides an (opinionated) implementation for a Doctrine-based repository.
2341

24-
### Example Usage
42+
#### Generator Command(s)
43+
44+
This command can be used to generate:
45+
46+
- The domain model class.
47+
- A repository class for the model.
48+
- The model's identity class as value object (optional).
49+
- A Doctrine database entity configuration, either as annotation or separate config file (optional).
50+
- A custom Doctrine type for the model's identity class (optional).
51+
52+
```bash
53+
Description:
54+
Creates a new domain model class
55+
56+
Usage:
57+
make:ddd:model [options] [--] [<name>]
58+
59+
Arguments:
60+
name The name of the model class (e.g. Customer)
61+
62+
Options:
63+
--aggregate-root Marks the model as aggregate root
64+
--entity=ENTITY Use this model as Doctrine entity
65+
--with-identity=WITH-IDENTITY Whether an identity value object should be created
66+
--with-suffix Adds the suffix "Model" to the model class name
67+
```
68+
69+
### AggregateRoot & Domain Events
70+
71+
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.
72+
73+
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.
74+
75+
#### Generator Command(s)
76+
77+
N/A
78+
79+
#### Example Usage
2580

2681
```php
2782
use GeekCell\Ddd\Contracts\Domain\Event as DomainEvent;
@@ -56,33 +111,51 @@ _Hint: If you want to dispatch an event directly, use `AggregateRoot::dispatch()
56111

57112
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.
58113

59-
## Repositories
114+
### Command & Query
115+
116+
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.
117+
118+
#### Generator Command(s)
119+
120+
These commands can be used to generate:
121+
122+
- A command and command handler class.
123+
- A query and query handler class.
124+
125+
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).
60126

61-
_coming soon..._
127+
```bash
128+
Description:
129+
Creates a new query|command class and handler
62130

63-
## Command & Query Bus
131+
Usage:
132+
make:ddd:query|command [<name>]
64133

65-
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) as "backend".
134+
Arguments:
135+
name The name of the query|command class (e.g. Customer)
136+
```
66137

67-
## Example Usage
138+
#### Example Usage
68139

69140
```php
70141
// src/Application/Query/TopRatedBookQuery.php
142+
71143
use GeekCell\Ddd\Contracts\Application\Query;
72144

73-
class TopRatedBooksQuery implements Query
145+
readonly class TopRatedBooksQuery implements Query
74146
{
75147
public function __construct(
76-
private readonly string $category,
77-
private readonly int $sinceDays,
78-
private readonly int $limit = 10,
148+
public string $category,
149+
public int $sinceDays,
150+
public int $limit = 10,
79151
) {
80152
}
81153

82154
// Getters etc.
83155
}
84156

85157
// src/Application/Query/TopRatedBookQueryHandler.php
158+
86159
use GeekCell\Ddd\Contracts\Application\QueryHandler;
87160

88161
#[AsMessageHandler]
@@ -96,14 +169,15 @@ class TopRatedBookQueryHandler implements QueryHandler
96169
public function __invoke(TopRatedBookQuery $query)
97170
{
98171
$books = $this->repository
99-
->findTopRated($query->getCategory(), $query->getSinceDays())
100-
->paginate($query->getLimit());
172+
->findTopRated($query->category, $query->sinceDays)
173+
->paginate($query->limit);
101174

102175
return $books;
103176
}
104177
}
105178

106179
// src/Infrastructure/Http/Controller/BookController.php
180+
107181
use GeekCell\Ddd\Contracts\Application\QueryBus;
108182

109183
class BookController extends AbstractController
@@ -124,97 +198,14 @@ class BookController extends AbstractController
124198
}
125199
```
126200

127-
## Supporting Tools
128-
129-
### Facades
130-
131-
Facades are heavily inspired by [Laravel's Facades](https://laravel.com/docs/facades) and are more or less singletons on steroids. They are basically a shortcut to services inside the DIC.
132-
133-
```php
134-
use GeekCell\DddBundle\Support\Facades\EventDispatcher;
135-
136-
EventDispatcher::dispatch($someEvent);
137-
138-
// same as: $container->get('event_dispatcher')->dispatch($someEvent);
139-
```
140-
141-
You can create your own facades by extending from `Facade` and implementing the `Facade::getFacadeAccessor()` method to return the DIC service alias.
142-
143-
```php
144-
use GeekCell\DddBundle\Support\Facades\Facade;
145-
146-
class Logger extends Facade
147-
{
148-
protected static function getFacadeAccessor(): string
149-
{
150-
return 'logger';
151-
}
152-
}
153-
```
154-
155-
Although facades are better testable than regular singletons, it is highly recommended to only use them sparringly and always prefer normal dependency injection when possible.
156-
157-
## Generator Commands
158-
159-
This bundle adds several [maker bundle](https://symfony.com/bundles/SymfonyMakerBundle/current/index.html) commands to generate commonly used components.
160-
161-
### Model / Repository
162-
163-
This command can be used to generate:
164-
165-
- The domain model class.
166-
- A repository class for the model.
167-
- The model's identity class as value object (optional).
168-
- A Doctrine database entity configuration, either as annotation or separate config file (optional).
169-
- A custom Doctrine type for the model's identity class (optional).
170-
171-
#### Command Output
172-
173-
```bash
174-
Description:
175-
Creates a new domain model class
176-
177-
Usage:
178-
make:ddd:model [options] [--] [<name>]
179-
180-
Arguments:
181-
name The name of the model class (e.g. Customer)
182-
183-
Options:
184-
--aggregate-root Marks the model as aggregate root
185-
--entity=ENTITY Use this model as Doctrine entity
186-
--with-identity=WITH-IDENTITY Whether an identity value object should be created
187-
--with-suffix Adds the suffix "Model" to the model class name
188-
```
189-
190-
### Query / Command
191-
192-
These commands can be used to generate:
193-
194-
- A query and query handler class.
195-
- A command and command handler class.
196-
197-
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).
198-
199-
#### Command Output
200-
201-
```bash
202-
Description:
203-
Creates a new query|command class and handler
204-
205-
Usage:
206-
make:ddd:query|command [<name>]
201+
### Controller
207202

208-
Arguments:
209-
name The name of the query|command class (e.g. Customer)
210-
```
203+
A standard Symfony controller, but augmented with command and query bus(es).
211204

212-
### Controller
205+
#### Generator Command
213206

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

216-
#### Command Output
217-
218209
```bash
219210
Description:
220211
Creates a new controller class
@@ -232,9 +223,11 @@ Options:
232223

233224
### Resource
234225

235-
This command can be used to generate an [Api Platform](https://api-platform.com/) resource. Minimum required version is [2.7](https://api-platform.com/docs/core/upgrade-guide/#api-platform-2730) for the PHP attributes support.
226+
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)
227+
228+
#### Generator Command
236229

237-
#### Command Output
230+
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).
238231

239232
```bash
240233
Description:

0 commit comments

Comments
 (0)