Skip to content

Commit f42ce46

Browse files
authored
Merge pull request #18 from patchlevel/add-more-docs
add more docs
2 parents d2c2b99 + 91e68f9 commit f42ce46

12 files changed

Lines changed: 375 additions & 157 deletions

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ a symfony integration of a small lightweight [event-sourcing](https://github.com
88

99
## Installation
1010

11-
```
11+
```bash
1212
composer require patchlevel/event-sourcing-bundle
1313
```
1414

15-
If you don't use the symfony flex recipe for this bundle, you need to follow
15+
> :warning: If you don't use the symfony flex recipe for this bundle, you need to follow
1616
this [installation documentation](docs/installation.md).
1717

1818
## Documentation
1919

20+
We recommend reading the documentation for the [library](https://github.com/patchlevel/event-sourcing) first,
21+
as this documentation only deals with bundle integration.
22+
2023
* [Repository](docs/repository.md)
2124
* [Event Bus](docs/event_bus.md)
2225
* [Processor](docs/processor.md)

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "patchlevel/event-sourcing-bundle",
33
"type": "symfony-bundle",
44
"license": "MIT",
5-
"description": "todo",
5+
"description": "symfony bundle for patchlevel/event-sourcing",
66
"keywords": [
77
"event-sourcing"
88
],
@@ -18,8 +18,8 @@
1818
}
1919
],
2020
"require": {
21-
"php": "^7.4|^8.0",
22-
"ext-json": "^7.4|^8.0",
21+
"php": "~7.4.0|~8.0.0",
22+
"ext-json": "~7.4.0|~8.0.0",
2323
"doctrine/dbal": "^3.1.4",
2424
"patchlevel/event-sourcing": "^1.0.0",
2525
"psr/simple-cache": "^1.0.1",
@@ -30,7 +30,7 @@
3030
"symfony/console": "^4.4.18|^5.1.10"
3131
},
3232
"require-dev": {
33-
"ext-pdo_sqlite": "^7.4|^8.0",
33+
"ext-pdo_sqlite": "~7.4.0|~8.0.0",
3434
"doctrine/migrations": "^3.3",
3535
"infection/infection": "^0.21.5",
3636
"patchlevel/coding-standard": "^1.1.1",

docs/event_bus.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Event Bus
2+
3+
This library uses the core principle called [event bus](https://martinfowler.com/articles/201701-event-driven.html).
4+
5+
For all events that are persisted (when the `save` method has been executed on the [repository](./repository.md)),
6+
the event will be dispatched to the `event bus`. All listeners are then called for each event.
7+
8+
## Symfony Event Bus
9+
10+
To use the [Symfony Messager](https://symfony.com/doc/current/messenger.html),
11+
you have to define it in messenger.yaml.
12+
It's best to call the bus "event.bus".
13+
An event bus can have 0 or n listener for an event.
14+
So "allow_no_handlers" has to be configured.
15+
16+
```yaml
17+
framework:
18+
messenger:
19+
buses:
20+
event.bus:
21+
default_middleware: allow_no_handlers
22+
```
23+
24+
We can then use this message or event bus in event sourcing:
25+
26+
```yaml
27+
patchlevel_event_sourcing:
28+
event_bus:
29+
service: event.bus
30+
```
31+
32+
## Command Bus
33+
34+
If you use a command bus or cqrs as a pattern, then you should define a new message bus.
35+
The whole thing can look like this:
36+
37+
```yaml
38+
framework:
39+
messenger:
40+
default_bus: command.bus
41+
buses:
42+
command.bus: ~
43+
event.bus:
44+
default_middleware: allow_no_handlers
45+
```

docs/installation.md

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,61 @@
1+
# Installation
12

2-
### Define your aggregates with class namespace and the table name
3+
If you are not using a symfony [flex](https://github.com/symfony/flex)
4+
or the [recipes](https://flex.symfony.com/) for it,
5+
then you have to carry out a few installation steps by hand.
36

4-
Class `App\Domain\Profile\Profile` is from the [libraries example](https://github.com/patchlevel/event-sourcing#define-aggregates) and is using the table name `profile`
7+
## Require package
58

9+
The first thing to do is to install packet if it has not already been done.
10+
11+
```bash
12+
composer require patchlevel/event-sourcing-bundle
13+
```
14+
15+
> :book: how to install [composer](https://getcomposer.org/doc/00-intro.md)
16+
17+
## Enable bundle
18+
19+
Then we have to activate the bundle in the `config/bundles.php`:
20+
21+
```php
22+
return [
23+
Patchlevel\EventSourcingBundle\PatchlevelEventSourcingBundle::class => ['all' => true],
24+
];
25+
```
26+
27+
If you don't have `config/bundles.php` then you need to add the bundle in the kernel:
28+
29+
```php
30+
class AppKernel extends Kernel
31+
{
32+
public function registerBundles()
33+
{
34+
$bundles = [
35+
new Patchlevel\EventSourcingBundle\PatchlevelEventSourcingBundle(),
36+
];
37+
}
38+
}
639
```
40+
41+
## Configuration file
42+
43+
Now you have to add a minimal configuration file here `config/packages/patchlevel_event_sourcing.yaml`.
44+
45+
```yaml
746
patchlevel_event_sourcing:
847
connection:
948
url: '%env(EVENTSTORE_URL)%'
10-
store:
11-
type: multi_table
12-
aggregates:
13-
profile:
14-
class: App\Domain\Profile\Profile
1549
```
50+
51+
## Dotenv
52+
53+
Finally we have to fill the ENV variable with a connection url.
54+
55+
```dotenv
56+
EVENTSTORE_URL: mysql://user:secret@localhost/app
57+
```
58+
59+
> :book: You can find out more about what a connection url looks like [here](https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url).
60+
61+
Now you can go back to [getting started](https://github.com/patchlevel/event-sourcing-bundle#getting-started).

docs/pipeline.md

Lines changed: 0 additions & 83 deletions
This file was deleted.

docs/processor.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Processor
2+
3+
The `processor` is a kind of [event bus](./event_bus.md) listener that can execute actions on certain events.
4+
A process can be for example used to send an email when a guest is checked in:
5+
6+
```php
7+
namespace App\Domain\Hotel\Listener;
8+
9+
use App\Domain\Hotel\Event\GuestIsCheckedIn;
10+
use Patchlevel\EventSourcing\Aggregate\AggregateChanged;
11+
use Patchlevel\EventSourcing\EventBus\Listener;
12+
use Symfony\Component\Mailer\MailerInterface;
13+
use Symfony\Component\Mime\Email;
14+
15+
final class SendCheckInEmailListener implements Listener
16+
{
17+
private MailerInterface $mailer;
18+
19+
private function __construct(MailerInterface $mailer)
20+
{
21+
$this->mailer = $mailer;
22+
}
23+
24+
public function __invoke(AggregateChanged $event): void
25+
{
26+
if (!$event instanceof GuestIsCheckedIn) {
27+
return;
28+
}
29+
30+
$email = (new Email())
31+
->from('noreply@patchlevel.de')
32+
->to('hq@patchlevel.de')
33+
->subject('Guest is checked in')
34+
->text(sprintf('A new guest named "%s" is checked in', $event->guestName()));
35+
36+
$this->mailer->send($email);
37+
}
38+
}
39+
```
40+
41+
If you have the symfony default service setting with `autowire`and `autoconfiger` enabled,
42+
the processor is automatically recognized and registered at the `Listener` interface.
43+
Otherwise you have to define the processor in the symfony service file:
44+
45+
```yaml
46+
services:
47+
App\Domain\Hotel\Listener\SendCheckInEmailListener:
48+
tags:
49+
- event_sourcing.processor
50+
```

0 commit comments

Comments
 (0)