0
votes

I've been reading about microservices and event sourcing and how it decouples services from one another. There are 2 concepts I am not clear on. First, if in a microservices architecture, each service can be developed independently how do we account for inter-service communication dependencies ?

For example, if Service A and Service B need to communicate, A needs to send an event to a central bus which B needs to listen for and act upon, but this seems to create a lot of dependencies. Now, if I am developing Service B, i need to know all of the events that Service A can generate. Also, if service A adds any new event, Service B also needs to change in order to handle that new event. All of this seems to create a dependency nightmare, and seems like you cannot truly develop each service 'independently'.

Secondly, how is a request/response type scenario handled at the API gateway or process manager level ? If the top level request fires off a bunch of cascading or interdependent events which need to be handled before returning a response to the caller, is this a scenario suited well for microservices ?

2

2 Answers

2
votes

Event sourcing is not event-driven architecture. Theoretically, you can have an internally event sourced Bounded Context/microservice in an ecosystem that doesn't use events for integration. You can also have non-event sourced BC's integrating via events.

Event-driven is one kind of asynchronous microservice integration. Synchronous integration is also possible. I don't know if that's what you implicitly contrast event-based integration with in your question, but the kind of dependency you have to manage is very similar in both cases.

So, no dependency nightmare that I can think of, at least no more than what you typically have when a subsystem A depends on a subsystem B.

Now, if I am developing Service B, i need to know all of the events that Service A can generate

No, you only subscribe to the ones you're interested in.

Also, if service A adds any new event, Service B also needs to change in order to handle that new event.

Again, not if you're not interested in it.

All of this seems to create a dependency nightmare, and seems like you cannot truly develop each service 'independently'.

As soon as one service depends on another, you obviously can't develop each service independently. You might have overinterpreted the kind of "independence" that loose coupling via events allows.

0
votes

First, if in a microservices architecture, each service can be developed independently how do we account for inter-service communication dependencies ?

Messages - you break direct coupling between the services by concentrating on the messages that they exchange, and concentrate on a change strategy for your schema that is forwards and backwards compatible (so that old services can read messages from new ones).

Greg Young writes about these ideas in his book of event versioning.

If the top level request fires off a bunch of cascading or interdependent events which need to be handled before returning a response to the caller, is this a scenario suited well for microservices ?

It's fine, actually, so long as you incorporate stale data into your design.

Fundamentally, the response to the query takes time to travel to the client; unless you are locking out all writers while the data is in transit, there is every possibility the "truth" of the system will have changed while the packets were in flight.

So you don't specify that queries describe the state "now", but rather that queries describe the state as of some time in the past. So if you send a query request to service A, and the result includes data from service B, then the query result is going to include A's cached copy of B's data as of some particular time.

So A's query of B to get the data is asynchronous with regards to the request sent to A. If refreshed data arrives from B in time to answer the query, great -- you answer with somewhat fresher stale data.

And yes, it can happen that C writes a change to B, gets an acknowledgement, then queries A... and gets back a response that does not include the changes that were already written and acknowledged.

So you build into the solution that there is no universal clock.

On the first question though, it seems as a developer of Service B, i would need to know all of the events that can be fired from Service A, and I would have a continual dependency if there are new events added.

Not all events. You need a common format (like avro, or json, or protocol buffers) so that the event representation can be deserialized, and you need the consumer to be able to recognize the events that it does care about, but events that the consumer doesn't recognize can fall through to a single default handler.