I know this question was already asked in a lot of ways and flavors, I wanted to add another way and a concrete example.
Basically I know the we should avoid synchronous communication, I was just wondering if there are some patterns to really avoid all of it. Let me give you a short example for a situation in which I wouldn't know how to make it asynchronous:
I have a service that is managing e.g. users, basically a DB that hast users saved and their configuration etc. Now another service that is the API Gates provides the Endpoint to register the user. And this is the point where the communication becomes a problem: if the register endpoint is called we somehow have to call synchronously the user service because we e.g. need the userId of the newly create user. So this is a very abstract example and needing the userId might not be needed in a lot of cases, but in generell I am curious about this patter:
A services needs to call another service in order to create a new resource but needs some kind of data of the newly created resource either to return it to it's caller or create locally some kind of connection between it's entities and the other services entities.
Is there some pattern for this or is this just a place where synchronous communication needs to happen?
CodePudding user response:
What you are describing is the Orchestration
vs Choreography
patterns:
In the
Orchestration
pattern a microservice invokes its dependencies directly, just like in your example, a microservice invokes another to register the user and then uses theuserId
from the response.On the other hand, we can have the
Choreography
pattern where we use need a message queue system, e.g.,Kafka
,RabbitMq
, to decouple the microservices. The same example would work as following:- Your User-Manager microservice will publish an event (command) of type
RegisterUser
to the message queue, containing the user information. - The API Gates subscribes to the events of type
RegisterUser
and whenever it gets an event of that type it will create the user normally. - Now, the API Gates must let everyone know that the user was created, so it will publish another event of type
UserCreated
containing the user information, e.g., theuserId
. - Finally, the User Manager must also subscribe the
UserCreated
events, so it can proceed with the flow.
- Your User-Manager microservice will publish an event (command) of type
With this approach the two microservices do not know each other, they are decoupled, and you can have any number of dependencies subscribing the events, i.e., you can add new dependencies without needing to change the code.