Ce que je ne sais pas très bien, c'est pourquoi vous réhydrateriez jamais vos agrégats à partir du magasin d'événements lui-même.
Parce que les "événements" sont le livre des records.
Si la projection de modifications dans des bases de données "en lecture" est si facile, pourquoi ne pas toujours projeter des modifications dans une base de données "en écriture" dont le schéma correspond parfaitement à votre modèle de domaine? Il s'agirait effectivement d'une base de données d'instantanés.
Oui; il est parfois utile d'optimiser les performances pour utiliser une copie mise en cache de l'état agrégé, plutôt que de régénérer cet état à partir de zéro à chaque fois. N'oubliez pas: la première règle d'optimisation des performances est "Ne pas". Cela ajoute une complexité supplémentaire à la solution, et vous préféreriez éviter cela jusqu'à ce que vous ayez une motivation commerciale convaincante.
Si tel est le cas, le magasin d'événements n'est-il utile que lors de la reconstruction de votre base de données "d'écriture" à la suite de modifications de schéma? Ou est-ce que je manque quelque chose de plus grand?
Il vous manque quelque chose de plus gros.
Le premier point est que si vous envisagez une solution issue d'un événement, c'est parce que vous vous attendez à ce qu'il y ait de la valeur à conserver l'historique de ce qui s'est passé, c'est-à-dire que vous souhaitez apporter des modifications non destructives .
C'est pourquoi nous écrivons à la boutique d'événements.
En particulier, cela signifie que chaque modification doit être écrite dans le magasin d'événements.
Les écrivains concurrents pourraient potentiellement soit détruire les écritures de l'autre, soit conduire le système à un état involontaire, s'ils ne sont pas au courant des modifications de l'autre. Ainsi, l'approche habituelle lorsque vous avez besoin de cohérence est d'adresser vos écritures à une position spécifique dans le journal (analogue à un PUT conditionnel dans une API HTTP). Une écriture qui a échoué indique à l'écrivain que sa compréhension actuelle du journal n'est pas synchronisée et qu'il devrait récupérer.
Revenir à une bonne position connue puis rejouer tous les événements supplémentaires, car ce point est une stratégie de récupération commune. Cette bonne position connue peut être une copie de ce qui se trouve dans le cache local ou une représentation dans votre magasin d'instantanés.
Sur la bonne voie, vous pouvez conserver un instantané de l'agrégat en mémoire; il vous suffit de vous adresser à un magasin externe lorsqu'il n'y a pas de copie locale disponible.
De plus, vous n'avez pas besoin d'être complètement rattrapé si vous avez accès au livre des records.
Ainsi, l'approche habituelle ( si vous utilisez un référentiel d'instantanés) consiste à le maintenir de manière asynchrone . De cette façon, si vous avez besoin de récupérer, vous pouvez le faire sans recharger et rejouer tout l'historique de l'agrégat.
Il existe de nombreux cas où cette complexité n'est pas intéressante, car les agrégats à grain fin avec des durées de vie limitées ne collectent généralement pas suffisamment d'événements pour que les avantages dépassent les coûts de maintenance d'un cache d'instantanés.
Mais quand c'est le bon outil pour le problème, charger une représentation périmée de l'agrégat dans le modèle d'écriture, puis le mettre à jour avec des événements supplémentaires, est une chose parfaitement raisonnable à faire.