Hi. Welcome to 'This is My Architecture', coming to you from Zurich in Switzerland.
Today, I'm joined by Michal from Coople.
- Hi, Michal. - Hi, Ross.
Thank you for inviting me here.
Such a pleasure. What can you tell us about Coople?
So Coople is a digital staffing platform.
We support finding, hiring, and pay-rolling of temporary and permanent workers.
We're in Switzerland and in the UK.
And we have more than 20,000 companies registered and more than 500,000 workers.
That is really nice.
Tell me what part of Coople are we going to be talking about?
So today, I'd like to tell you how we migrated our system
from a traditional data center to AWS.
We have had a CQRS Event Source node on it which we moved to AWS.
Today, we are gradually migrating functionalities
to domain serverless services.
That is nice.
Event Sourcing CQRS is some of my favorite architecture patterns
that I'm really keen to get into the details.
Why don't you take us through what's on the board?
So when a client wants to write to the system,
they send us a CQRS command.
It goes to AWS Lambda.
This Lambda processes and validates the request.
And if everything is fine, it emits an event to the event store.
Our event store is a table in DynamoDB.
Then this event goes through DynamoDB stream to Lambda.
Our streamer puts the event to SNS FIFO
and also archives data to S3.
From SNS FIFO, we do a fan-out.
Every service can subscribe to an event
by simply attaching SQS to SNS.
Now, SNS FIFO is a relatively new service in AWS.
If we were to go back in time for a year, what would this look like?
So before we had a normal SNS and SQS.
We moved it to SNS FIFO and SQS FIFO to simplify the architecture.
This simple change helped us to remove additional components
which were maintaining the events ordering within one aggregate and events cache in the handler.
Okay, great to hear. So what happens next?
So Lambda pulls events from SQS.
Here we handle all the business events
and we write the data to our read models.
These are the projections for reading the data from the system.
When a client wants to read the data, they send us a CQRS query to Lambda.
Lambda reads this data from the read model and sends it back to the client.
So having read models in something like DynamoDB makes a lot of sense.
You get away from having to build the queries at runtime,
but how do you know what read models you need for your customers?
So at the beginning we don't know this.
We start quite usually with MySQL database.
Over time, we learn what access patterns are used
and then we can change this database to a different one
that better suits the access pattern used by the microservice.
Okay, okay, nice.
I want to go back a bit where, right at the beginning,
you mentioned that you are migrating from a CQRS monolith application.
How does that fit in to what you've got on AWS now?
So we still use the monolith, but from MySQL event store,
we migrated to a table in DynamoDB.
Our monolith uses the same table as all the microservices.
The difference is that for building projections,
it uses a GSI which maintains a global order for all events in the system.
Okay, now as elegant and as good as this architecture looks,
it's always constantly evolving.
What's next?
So right now we are starting to build new contexts in the Coople.
It means that a new context is getting a separate event store.
This new context will have a separate business event which is internal for this context.
And when a new context wants to communicate with an old part of the system,
they will be using public events which will be sent over EventBridge.
Okay. Michal, thank you for sharing your architecture with us today.
You're welcome.
And thank you for watching 'This is My Architecture.'