In de wereld van softwareontwikkeling zijn er zinnen die klinken als een bezwering van een tovenaar. Bijvoorbeeld Event sourcing en Command Query Responsibility Segregation (CQRS). Het lijken misschien mysterieuze bezweringen, maar het zijn eigenlijk super nuttige architectuurprincipes om schaalbare en evolutionaire softwaresystemen te ontwerpen en te maken.
In dit artikel gaan we twee magische concepten van de Event sourcing wereld ontrafelen: Event Upcasting en Event Replaying. Inzicht in deze concepten is van vitaal belang omdat naarmate bedrijven zich uitbreiden en inspelen op nieuwe vragen uit de markt, de structuur en inhoud van evenementen mee moeten evolueren. We zullen ons in deze concepten verdiepen, hun mysteries onthullen en illustreren hoe ze zowel technische tovenaars als zakelijke tovenaars ten goede komen. Onze reis zal worden geleid door concrete voorbeelden, gebruikmakend van het Axon Framework om hun praktische toepassing te demonstreren.
Bouwen op de basis
Voordat we beginnen aan deze magische reis van Event Upcasting en Event Replaying, is het essentieel om een sterke basis te leggen in event sourcing en CQRS.
- 🧙 Voor bedrijfsprofessionals: Geen kristallen bol nodig. Als je de basisprincipes van event sourcing en CQRS begrijpt, kun je weloverwogen beslissingen nemen over je digitale koninkrijk. Het is je ticket om de taal van de technische tovenaars vloeiend te spreken. Voor meer mystieke inzichten, bekijk lezingen zoals “Capture, Keep, and Unlock All Your Data,” van Michael Schoenmaekers, speciaal voor jou ontworpen.
- 🧙 Voor ontwikkelaars: Stel event sourcing en CQRS voor als de spreuken die krachtige en veerkrachtige systemen creëren. Om de tovenaars van het digitale rijk te worden, is het beheersen van deze bezweringen een must. Maak je geen zorgen; je hebt geen Zweinsteinbrief nodig. Ga gewoon naar Axon Academy om deze magische vaardigheden vrij te spelen en hun gratis cursussen te volgen.
Wat is event upcasting?
Stel je voor dat je je favoriete betoverde zwaard upgradet zonder ook maar iets van zijn magische eigenschappen te verliezen. Dat is precies wat Event Upcasting doet. Het transformeert historische gebeurtenissen in een glanzend nieuw formaat met behoud van al hun oorspronkelijke charme.
- 🛡️Voor zakelijke professionals: Upcasting zorgt ervoor dat uw systeem naadloos wijzigingen kan verwerken, vermindert het risico op gegevensinconsistenties en behoudt historische gegevens.
- 🛡️Voor ontwikkelaars: Event Upcasting stelt je in staat om je evenementenschema te evolueren zonder bestaande systemen te breken. Deze flexibiliteit is cruciaal voor het aanpassen aan veranderende vereisten.
Wat is Event Replaying?
Stel je dit eens voor: het is filmavond in je kasteel en je besluit om je favoriete epische verhaal te herbekijken. Event Replaying is vergelijkbaar, maar het gaat erom dat je het verhaal van je hele koninkrijk reconstrueert door gebeurtenissen uit het verleden opnieuw uit te voeren. Het is alsof je alle magische wezens en personages uit de geschiedenis van je koninkrijk oproept om hun avonturen te herbeleven.
- 🎬 Voor zakelijke professionals: Hiermee kunt u historische analyses uitvoeren, controlesporen maken en naleving van de regelgeving garanderen, waardoor het gegevensbeheer en de besluitvorming worden verbeterd.
- 🎬 Voor ontwikkelaars: Event Replaying is een krachtig hulpmiddel voor het debuggen, controleren en onderhouden van gegevensconsistentie in uw systemen. Bovendien kunt u bestaande code eenvoudiger uitbreiden omdat u uw gegevenstabellen kunt verwijderen en ze opnieuw kunt vullen door de event store of nieuwe modules kunt maken op basis van bestaande events en gegevens.
Hoe Event Upcasting en Event Replaying samenwerken
Deze twee magische praktijken bundelen vaak hun krachten, vooral wanneer je op een zoektocht bent om gegevens te migreren van de ene evenementenschemaversie naar de andere.
- 🤝 Voor bedrijfsprofessionals: Deze samenwerking zorgt voor naadloze overgangen tussen gegevensstructuren en verbetert de harmonie en betrouwbaarheid van de gegevens in het koninkrijk. Het houdt uw digitale koninkrijk wendbaar en klaar om te reageren op de steeds veranderende wensen van de markt en uw trouwe onderdanen.
- 🤝 Voor ontwikkelaars: De samenwerking tussen Upcasting en Replaying is uw geheime wapen om gegevenswijzigingen effectief te beheren. Het is als het toevoegen van nieuwe spreuken aan je repertoire, waarbij innovatie wordt gestimuleerd terwijl de compatibiliteit met je oude charmes wordt gewaarborgd.
Laten we deze samenwerking eens in actie zien aan de hand van het verhaal van de toverdrankjesbezorger “Bubbels”
Een verhaal over levering van drankjes - de heerlijke uitbreiding
In het begin leverde onze winkel alleen in Nederland, met een specifieke gebeurtenis in hun bestellijst:
Event For Business Professionals:
Potion Order Placed Event (Version 1.0)
Order
ID- Customer Name
- Dutch Address
Event For Developers:
@Revision("1.0")
public class PotionOrderPlacedEvent{
private String orderId;
private String customerName;
private DutchAddress address;
// ...
}
public class DutchAddress{
private String postalCode;
private String houseNumber;
private String addition;
// ...
public String getAddress() {
return postalCode + " " + houseNumber + " " + addition;
}
}
De zoektocht
Nu had het Nederlandse adres een aantal eigenaardige eigenschappen: postcode, huisnummer en toevoeging. Maar zie! Het nieuws kwam dat klanten over de grens in België ook snakten naar drankjes. De uitdaging? Belgische adressen hadden straatnamen nodig, Nederlandse niet. Dit is een concreet voorbeeld van hoe bedrijven uitbreiden en inspelen op nieuwe vragen uit de markt. Dit betekent dat de structuur en inhoud van het PotionOrderPlacedEvent mee moet evolueren.
Hoe kon “Bubbles” zowel het Nederlandse als het Belgische land bedienen zonder hun huidige bedrijfsevenement te verstoren? Het antwoord: Upcasting!
Stap 1: address creëren, de vormveranderaar
Eerst toverde “Bubbles” een nieuw 'Address'-object tevoorschijn dat kon shapeshiften in een Nederlands of Belgisch adres, dankzij de 'getCountry'- en 'getAddress'-spreuken:
Stap 1 voor zakelijke professionals:
🪄 Address (De gedaanteverwisselaar):
- `getAddress()` spreuk => toont het volledige adres in één zin
- `getCountry()`spreuk => laat zien of het een Nederlands of Belgisch adres is door het land België of Nederland terug te geven
Vervolgens wordt de shape shifter gebruikt:
🏡 DutchAddress:
- postal code
- house number
- addition
- `getAddress()` spell => toont het volledige Nederlandse adres in één zin
- `getCountry()` spell => toont dat het een Nederlands adres is door NETHERLANDS te geven
🏡 BelgianAddress:
- postal code
- street name
- house number
- addition
- `getAddress()` spell => toont het volledige Belgische adres in één zin
- `getCountry()` spell => toont dat het een Belgisch adres is door BELGIUM te geven
Stap 1 voor ontwikkelaars:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "country")
@JsonSubTypes({
@JsonSubTypes.Type(value = DutchAddress.class, name = "NETHERLANDS"),
@JsonSubTypes.Type(value = BelgianAddress.class, name = "BELGIUM"),
})
public interface Address {
String getAdress();
String getCountry();
}
public class DutchAddress implements Address {
private String postalCode;
private String houseNumber;
private String addition;
// ...
public String getAddress (){
return postalCode + " " + houseNumber + " " + addition;
}
@Override
public String getCountry () {
return "NETHERLANDS";
}
}
public class DutchAddress implements Address {
private String postalCode;
private String houseNumber;
private String addition;
// ...
public String getAddress (){
return postalCode + " " + houseNumber + " " + addition;
}
@Override
public String getCountry () {
return "BELGIUM";
}
}
Stap 2: een update van het evenement maken
We gebruikten deze nieuw gevonden 'Address' shapeshifter in een nieuwe versie van het evenement, zodat we zowel aan Nederlandse als Belgische adressen konden leveren.
Stap 2 voor zakelijke professionals:
Potion Order Placed Event (Version 2.0):
- Order ID
- Customer Name
- Shape shifter Address
Stap 2 voor Developers:
@Revision ("2.0")
public class PotionOrderPlacedEvent {
private String orderId;
private String customerName;
private Address address;
//...
}
Stap 3: aanschouw de Upcaster Spell - transformeer het oude naar het nieuwe
De Order Scroll bevat onze geschiedenis met de oudere gebeurtenissen en we willen onze geschiedenis niet overschrijven. Een geschiedenis ligt in het verleden en mag dus nooit worden aangepast. Op alle bestellijsten moet echter duidelijk worden vermeld of de bezorgers naar België of Nederland moeten vliegen. Hier komt de transformatie (upcaster) spreuk om de hoek kijken die het mogelijk maakt om de order scroll, onze geschiedenis, te gebruiken in al onze bezorglijsten. Dit wordt gedaan door de landeigenschap toe te voegen bij het lezen van oude gebeurtenissen uit de order scroll. Door deze verandering konden “Bubbles” hun toverdrankrijk uitbreiden naar België zonder hun Nederlandse avonturen uit het oog te verliezen.
Stap 3 voor zakelijke professionals:
🧙 Magische Upcaster Spell
- Detecteert oude ordegebeurtenissen (versie 1.0)
- Transformeert ze in nieuwe ordegebeurtenissen (versie 2.0) met de 'country'-spreuk ingesteld op “NETHERLANDS”.
Stap 3 voor developers:
@Component
@Order(0)
public class PotionOrderPlacedEvent1to2Upcaster extends SingleEventUpcaster {
public static final SimpleSerializedType TARGET_TYPE =
new SimpleSerializedType("com.bubbels.events.PotionOrderPlacedEvent", "1.0");
@Override
public boolean canUpcast (IntermediateEventRepresentation intermediateRespresentation){
return intermediateRepresentation.getType().equals(TARGET_TYPE);
}
@Override
public IntermediateEventRepresentation doUpcast(
IntermediateEventRepresentation intermediateRepresentation)}
return intermediateRepresentation.upcastPayload(
new SimpleSerializedType (TARGET_TYPE.getName(), "2.0"),
ObjectNode.class,
event -> {
event.set ("country", "NETHERLANDS");
return event;
}
);
}
}
Stap 4: de upcaster-spell uitspreken en de leveringslijsten maken
Maar wacht, het feest is nog niet voorbij! Hoewel we onze geschiedenis nu kunnen lezen alsof we altijd een landhuis hebben gehad, moeten we onze leveringslijsten bijwerken zodat we kunnen zien aan welk land we leveren. Wat moeten we doen? Gebeurtenis opnieuw afspelen!
De oude bezorglijst zag er als volgt uit:
We verbranden alle gegevens in de leveringslijst en roepen de order scroll op (onze geschiedenis). We vertellen de scroll dat we de gegevens hebben verwijderd (in ontwikkelaarstaal => door het token te verwijderen) en de scroll zal de upcaster-spell gebruiken om de leverlijst opnieuw te vullen met het landveld.
Als we nu nieuwe orders ontvangen, ziet onze lijst er als volgt uit:
🔮 Op zoek naar meer kennis?
Als u:
- graag dieper wilt duiken in de wereld van Event Upcasting en Event Replaying
- of als je specifieke vragen hebt
- of hunkert naar meer betoverende inhoud
- of op zoek bent naar een systeem dat je kunt gebruiken als een betrouwbaar Zwitsers zakmes