I'm coming from the monolith background, using a single large relational database. From my research, many proponents of the microservice architecture favor the event-driven rather than REST driven architecture. The following question applies to inter-service communication, between bounded contexts (in DDD terms) and NOT to events within a BC, nor event sourcing.
As I understand it, to decouple services from each other, a message bus such as RabbitMQ is used to publish a domain event, which contains info related to the event, such as UserCreated
or UserSuspended
, and other bounded contexts can make use of it to store the data they need in their own database. For example, a billing service might need just user id
and status
so that it doesn't generate invoices for suspended users. With this "cached" user data, it doesn't have to do a REST API call to the User
BC to get the information. This is considered "autonomous" rather than "authority".
A couple questions:
- How can new services be deployed? In the above example, assume the User service exists but the Billing service is being built. It needs to seed its database with all the existing user statuses. Assuming I don't have the entire history of events available in the User service (as with RabbitMQ), this means that one of two options need to happen: A) the User service needs to provide an API endpoint that the new Billing service can use in its migrations to get user statuses. Additional work needs to be done in the User service if this endpoint doesn't exist. Or B), the Billing deployment/migration script can break responsibilities one time and directly get access to the User database. But this means devs from Billing need to learn the data schema from another service.
- How can bugs that cause inconsistencies be fixed? For example, somehow a developer broke the publisher and no
UserCreated
orUserSuspended
events get produced for an hour. The bug is noticed and fixed, but a whole hour's worth of events are missing. Two possible solutions: A) the dev fromUser
BC manually publishes the missing events. He would need to figure out which events were missed (if even possible), then write scripts to construct them (time consuming.) This would be additionally problematic if new events already fired that made the original missing ones obsolete. Or B) the other bounded contexts could be notified to run scripts that update their data via the User's API (returning to the authority model)
Another underlying question here is, in inter-service communication, where is the ultimate source of truth for external events? Is it in the event stream, or in the API provided by the bounded contexts?
I love the idea of autonomous systems to reduce coupling, remove dependencies, and to let services evolve faster, but I'm afraid of situations that cause inconsistencies that wouldn't happen in the authoritative structure, where data is always up-to-date via live API calls. Any tips would be greatly appreciated.