Skip to content

Commit 07d296a

Browse files
dgafkagitbook-bot
authored andcommitted
GITBOOK-848: No subject
1 parent 506fd3a commit 07d296a

32 files changed

+571
-214
lines changed
21.5 KB
Loading

.gitbook/assets/event-strea.png

8.95 KB
Loading

.gitbook/assets/events.png

11.8 KB
Loading

.gitbook/assets/first-request.png

37.6 KB
Loading

.gitbook/assets/paritioned_stream.png

66.8 KB
Loading

.gitbook/assets/partioned_stream.png

66.8 KB
Loading

.gitbook/assets/partition_key.png

68.2 KB
Loading

.gitbook/assets/request-two.png

40.2 KB
Loading
12.1 KB
Loading
28.7 KB
Loading
19.2 KB
Loading
21.6 KB
Loading

SUMMARY.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,26 @@
4747
* [Message Headers](modelling/extending-messaging-middlewares/message-headers.md)
4848
* [Interceptors (Middlewares)](modelling/extending-messaging-middlewares/interceptors.md)
4949
* [Event Sourcing](modelling/event-sourcing/README.md)
50+
* [Installation](modelling/event-sourcing/installation.md)
5051
* [Event Sourcing Introduction](modelling/event-sourcing/event-sourcing-introduction/README.md)
51-
* [Creating New Event Stream](modelling/event-sourcing/event-sourcing-introduction/creating-new-event-stream.md)
52-
* [Applying Events](modelling/event-sourcing/event-sourcing-introduction/applying-events.md)
52+
* [Working with Event Streams](modelling/event-sourcing/event-sourcing-introduction/working-with-event-streams.md)
53+
* [Event Sourcing Aggregates](modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/README.md)
54+
* [Working with Aggregates](modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/working-with-aggregates.md)
55+
* [Applying Events](modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/applying-events.md)
56+
* [Different ways to Record Events](modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/different-ways-to-record-events.md)
57+
* [Making Stream immune to changes](modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/making-stream-immune-to-changes.md)
58+
* [Snapshoting](modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/snapshoting.md)
5359
* [Working with Metadata](modelling/event-sourcing/event-sourcing-introduction/working-with-metadata.md)
5460
* [Event versioning](modelling/event-sourcing/event-sourcing-introduction/event-versioning.md)
55-
* [Setting up Projections](modelling/event-sourcing/setting-up-projections/README.md)
61+
* [Event Stream Persistence Strategy](modelling/event-sourcing/event-sourcing-introduction/persistence-strategy.md)
62+
* [Projections Introduction](modelling/event-sourcing/setting-up-projections/README.md)
5663
* [Choosing Event Streams for Projection](modelling/event-sourcing/setting-up-projections/choosing-event-streams-for-projection.md)
57-
* [Persistence](modelling/event-sourcing/persistence/README.md)
58-
* [Persistence Strategy](modelling/event-sourcing/persistence/persistence-strategy.md)
59-
* [Snapshoting](modelling/event-sourcing/persistence/snapshoting.md)
60-
* [Executing and Managing](modelling/event-sourcing/executing-and-managing/README.md)
61-
* [Running Projections](modelling/event-sourcing/executing-and-managing/running-projections.md)
62-
* [Projection CLI Actions](modelling/event-sourcing/executing-and-managing/projection-cli-actions.md)
63-
* [Access Event Store](modelling/event-sourcing/executing-and-managing/access-event-store.md)
64-
* [Emitting events](modelling/event-sourcing/emitting-events.md)
65-
* [Projections with State](modelling/event-sourcing/projections-with-state.md)
64+
* [Executing and Managing](modelling/event-sourcing/setting-up-projections/executing-and-managing/README.md)
65+
* [Running Projections](modelling/event-sourcing/setting-up-projections/executing-and-managing/running-projections.md)
66+
* [Projection CLI Actions](modelling/event-sourcing/setting-up-projections/executing-and-managing/projection-cli-actions.md)
67+
* [Access Event Store](modelling/event-sourcing/setting-up-projections/executing-and-managing/access-event-store.md)
68+
* [Projections with State](modelling/event-sourcing/setting-up-projections/projections-with-state.md)
69+
* [Emitting events](modelling/event-sourcing/setting-up-projections/emitting-events.md)
6670
* [Recovering, Tracing and Monitoring](modelling/recovering-tracing-and-monitoring/README.md)
6771
* [Resiliency](modelling/recovering-tracing-and-monitoring/resiliency/README.md)
6872
* [Retries](modelling/recovering-tracing-and-monitoring/resiliency/retries.md)

modelling/event-sourcing/event-sourcing-introduction/creating-new-event-stream.md

Lines changed: 0 additions & 159 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Event Sourcing Aggregates
2+

modelling/event-sourcing/event-sourcing-introduction/applying-events.md renamed to modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/applying-events.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Applying Events
22

3-
As [mentioned earlier](./), Events are stored in form of a Event Stream.\
3+
As [mentioned earlier](../), Events are stored in form of a Event Stream.\
44
Event Stream is audit of Events, which happened in the past. \
55
However to protect our business invariants, we may want to work with current state of the Aggregate to know, if given action is possible or not (business invariants). 
66

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Different ways to Record Events
2+
3+
## Two ways of setting up Event Sourced Aggregates
4+
5+
There are two ways we can configure our Aggregate to record Events. 
6+
7+
### 1) Pure Event Sourced Aggregate
8+
9+
This way of handling events does allow for pure functions. This means that actions called on the Aggregate returns Events and are not changing internal state of Aggregate.
10+
11+
```php
12+
#[EventSourcingAggregate] // 1
13+
class Ticket
14+
{
15+
use WithAggregateVersioning; // 2
16+
17+
#[Identifier] // 1
18+
private string $ticketId;
19+
private string $ticketType;
20+
21+
#[CommandHandler] // 2
22+
public static function register(RegisterTicket $command) : array
23+
{
24+
return [new TicketWasRegistered($command->getTicketId(), $command->getTicketType())];
25+
}
26+
27+
#[CommandHandler] // 2
28+
public function close(CloseTicket $command) : array
29+
{
30+
return [new TicketWasClosed($this->ticketId)];
31+
}
32+
33+
#[EventSourcingHandler] // 4
34+
public function applyTicketWasRegistered(TicketWasRegistered $event) : void
35+
{
36+
$this->ticketId = $event->getTicketId();
37+
$this->ticketType = $event->getTicketType();
38+
}
39+
}
40+
```
41+
42+
1. `EventSourcingAggregate` and `Identifier` [works exactly the same as State-Stored Aggregate](../../../command-handling/state-stored-aggregate/).
43+
2. Event Sourced Aggregate must provide version. You may leave it to `Ecotone` using `WithAggregateVersioning` or you can implement it yourself.
44+
3. `CommandHandler`for event sourcing returns events generated by specific method. This will be passed to the [`Repository`](../../../command-handling/repository.md) to be stored. 
45+
4. `EventSourcingHandler` is method responsible for reconstructing `Aggregate` from previously created events. At least one event need to be handled in order to provide `Identifier`.
46+
47+
### 2) Internal Recorder Aggregate
48+
49+
This way of handling events allow for similarity with [State Stored Aggregates](../../../command-handling/state-stored-aggregate/).\
50+
This convention requires changing internal state of Aggregate to record Events. \
51+
Therefore Pure ES Aggregate is recommended as it's not require for any internal state changes in most of the scenarios. \
52+
However ES Aggregate with Internal Recorder may be useful for projects migrating with other solutions, or when our team is heavily used to working this way.
53+
54+
```php
55+
#[EventSourcingAggregate]
56+
class Basket
57+
{
58+
use WithEvents; // 1
59+
use WithVersioning;
60+
61+
#[Identifier]
62+
private string $id;
63+
64+
#[CommandHandler] // 2
65+
public static function create(CreateBasket $command) : static
66+
{
67+
$basket = new static();
68+
$basket->recordThat(new BasketWasCreated($command->getId()));
69+
70+
return $basket;
71+
}
72+
73+
#[CommandHandler] // 2
74+
public function addProduct(AddProduct $command) : void
75+
{
76+
$this->recordThat(new ProductWasAddedToBasket($this->id, $command->getProductName()));
77+
}
78+
79+
#[EventSourcingHandler]
80+
public function applyBasketWasCreated(BasketWasCreated $basketWasCreated)
81+
{
82+
$this->id = $basketWasCreated->getId();
83+
}
84+
}
85+
```
86+
87+
1. In order to make use of alternative way of handling events, we need to provide trait **WithEvents**.
88+
2. Command Handlers instead of returning events are acting the same as [State Stored Aggregates](../../../command-handling/state-stored-aggregate/).\
89+
All events which will be published using `recordThat`will be passed to the [`Repository`](../../../command-handling/repository.md) to be stored. 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Making Stream immune to changes
2+
3+
Changes in the Application will happen. After some time we may want to refactor namespaces, change the name of Aggregate or an Event. However those kind of changes may break our system, if we already have production data which references to any of those. \
4+
Therefore to make our Application to immune to future changes we need a way to decouple the code from the data in the storage, and this is what Ecotone provides.
5+
6+
## Custom Stream Name
7+
8+
Our Event Stream name by default is based on the Aggregate Class name. Therefore to make it immune to changes we may provide custom Stream Name. To do it we will apply `Stream` attribute to the aggregate:
9+
10+
```php
11+
#[Stream("basket_stream")]
12+
class Basket
13+
```
14+
15+
Then tell the projection to make use of it:
16+
17+
```php
18+
#[Projection(self::PROJECTION_NAME, "basket_stream")]
19+
class BasketList
20+
```
21+
22+
## Custom Aggregate Type
23+
24+
By default events in the stream will hold Aggregate Class name as `AggregateType`. \
25+
You may customize this by applying `AggregateType` attribute to your Aggregate.
26+
27+
```php
28+
#[AggregateType("basket")]
29+
class Basket
30+
```
31+
32+
{% hint style="info" %}
33+
You may wonder what is the difference between Stream name and Aggregate Type. \
34+
By default the are the same, however we could use the same Stream name between different Aggregates, to store them all together within same Table. \
35+
\
36+
This may useful during migration to next version of the Aggregate, where we would want to hold both versions in same Stream.
37+
{% endhint %}
38+
39+
## Storing Events By Names
40+
41+
To avoid storing class names of Events in the `Event Store` we may mark them with name:
42+
43+
```php
44+
#[NamedEvent("basket.was_created")]
45+
class BasketWasCreated
46+
{
47+
public const EVENT_NAME = "basket.was_created";
48+
49+
private string $id;
50+
51+
public function __construct(string $id)
52+
{
53+
$this->id = $id;
54+
}
55+
56+
public function getId(): string
57+
{
58+
return $this->id;
59+
}
60+
}
61+
```
62+
63+
This way Ecotone will do the mapping before storing an Event and when retrieving the Event in order to deserialize it to correct class.

modelling/event-sourcing/persistence/snapshoting.md renamed to modelling/event-sourcing/event-sourcing-introduction/event-sourcing-aggregates/snapshoting.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class EventSourcingConfiguration
3333
2. `$thresholdTrigger` - amount of events for interval of taking a snapshot
3434
3. `$documentStore` - reference to document store which will be used for saving/retrieving snapshots
3535

36-
To set up snapshots we will define [ServiceContext](../../../messaging/service-application-configuration.md) configuration.
36+
To set up snapshots we will define [ServiceContext](../../../../messaging/service-application-configuration.md) configuration.
3737

3838
```php
3939
#[ServiceContext]
@@ -47,7 +47,7 @@ public function aggregateSnapshots()
4747
```
4848

4949
{% hint style="info" %}
50-
Ecotone make use of [Document Store](../../../messaging/document-store.md) to store snapshots, by default it's enabled with event-sourcing package. \
50+
Ecotone make use of [Document Store](../../../../messaging/document-store.md) to store snapshots, by default it's enabled with event-sourcing package. \
5151
\
5252
If you want to clean the snapshots, you can do it manually. Snapshots are stored in `aggregate_snapshots` collection.
5353
{% endhint %}

0 commit comments

Comments
 (0)