Supposons que je voudrais obtenir une projection globale d'un point donné à temps et j'utilise l'architecture basée sur les CQRS et l'événement. P>
En outre, j'ai à la fois lire et écrire une base de données. La première est alimentée par des événements et il y a des projections globales à utiliser par l'interface utilisateur. p>
Ma question est - Quelle est la meilleure approche pour reconstruire l'état d'agrégat d'un point donné dans une telle architecture, et brièvement comment il devrait ressembler d'un point de vue architectural. P>
Remarque: je veux renvoyer une telle projection au côté du client. P>
3 Réponses :
Cela dépend de savoir si vous attendez beaucoup d'événements par agrégat. P>
Si vous le faites, vous pouvez utiliser des instantanés. Enregistrez l'état d'un agrégat à un moment donné. Ensuite, vous pouvez lire cet instantané et appliquer tous les événements arrivés après l'instantané. P>
Si vous ne vous attendez pas à beaucoup d'événements, il suffit de lire tous les événements de la mendicité du flux et de reconstruire cet agrégat. Dans ce cas, l'instantané peut rendre les choses plus complext et même des choses ralentissées. P>
Voici quelques ressources que vous pouvez vérifier: p>
https://blog.jonathanoliver.com/event-sourcing-and- Instantanés / https://martinfowler.com/eaadev/eventsourcing.html P>
Si vous avez une architecture d'approvisionnement d'événements, cela signifie que vous stockez déjà votre événement dans un référentiel de magasin d'événements "APPEND-UNIQUEMENT". D'un point de vue de l'architecture, vous devez désérialiser des événements et les appliquer à nouveau (dans la projection de mémoire) pour reconstruire l'état de votre agrégat.
EventStore Interface ressemblerait à quelque chose comme ceci: P>
public abstract class EventSourcedRootEntity { private List<DomainEvent> mutatingEvents; private int unmutatedVersion; public int mutatedVersion() { return this.unmutatedVersion() + 1; } public List<DomainEvent> mutatingEvents() { return this.mutatingEvents; } public int unmutatedVersion() { return this.unmutatedVersion; } protected EventSourcedRootEntity(List<DomainEvent> anEventStream, int aStreamVersion) { for (DomainEvent event : anEventStream) { this.mutateWhen(event); } this.setUnmutatedVersion(aStreamVersion); } }
En supposant que le nombre d'événements per-agrégat est petit, vous pouvez répondre à une demande d'un point à temps débutant en streaming les événements pour cet agrégat jusqu'à présent dans une projection en mémoire. Si votre saillie s'appuie uniquement sur des événements d'un type d'agrégat, vous avez effectué simplement la projection. Si vous avez trop d'événements par agrégat pour cela, vous pouvez potentiellement stocker des instantanés périodiques pour chaque projection globale (peut-être tous les 100 événements pour un agrégat particulier, par exemple). P>
L'attelage est que vous pouvez également avoir besoin d'autres informations dans votre projection, à partir d'autres flux d'événements. Cela le rend plus compliqué. Les options incluent: p>