Search code examples
microservicescqrsevent-driven

How to query in a Event Driven Microservice architecture?


Let suppose the following simple UC based on a CQRS architecture:

We have a backend managing a Business Object, let says a Movie.

  • This backend is composed of 2 Microservices: a CommandManager (Create/Update/Delete Movie) and a QueryManager (Query Movie)
  • We have a frontend that offer a web page for creating a new Movie and this action lead automatically to another web page describing the Movie.

A simple way to do that is:

  • A web page collect movie information using a form and send them to the frontend.
  • The frontend make a POST request to the CommandManager
  • The CommandManager write the new movies to the datastore and return the movie key
  • The frontend make a GET using this key to the QueryManager
  • The QueryManager looks for the Movie in the Datastore using the key and return it.
  • The frontend deliver the page with the Movie Information.

Ok, now I want to transform this UC in a more Event Driven way. Here is the new flow:

  • A web page collect movie information using a form and send them to the frontend.
  • The frontend write a Message in the BUS with the new movie information
  • The CommandManager listen the BUS and create the new movies in the datastore. Eventually, it publish a new message in the BUS specifying that a new Movie has been created.

At this point, the frontend is no more waiting for a response due to the fact that this kind of flow is asynchronous. How could we complete this flow in order to forward the user to the Movie Information Web page? We should wait that the creation process is done before querying the QueryManager.

In a more general term, in a asynchronous architecture based on bus/event, how to execute Query used to provide information in a web page?


Solution

  • In addition to @VoiceOfUnreason's answer,

    If the two microservices are RESTFul, the CommandManager could return a 202 Accepted with a link pointing to the resource that will be created in the future. The client could then poll that resource until the server responds with a 200 OK.

    Another solution would be that the CommandManager would return a 202 Accepted with a link pointing to a command/status endpoint. The client would poll that endpoint until the status is command-processed (including the URL to the the actual resource) or command-failed (including a descriptive message for the failure).

    These solutions could be augmented by sending the status of all processed commands using Server Sent Events. In this way, the client gets notified without polling.

    If the client is not aware that the architecture is asynchronous, a solution is to use an API gateway that blocks the client's request until the upstream microservice processes the command and then to respond with the complete resource's data.