How To Implement Asynchronous Interactions Between Microservices

Oleksii Dushenin
4 min readNov 17, 2021

In a previous post, How To Implement Synchronous Interactions Between Microservices, the synchronous interactions (HTTP/HTTPS) were reviewed. As you can see, there can be issues with such applications that should be addressed. For instance, how the application should behave if some service does not work as expected. What if services constantly need data from another service? Can that service cope with the load? It is just a few problematic places that can be found in Microservices with Synchronous Interactions. In this post, Asynchronous Interactions Between Microservices will be reviewed.

Let’s create an example to show the use case. The diagram from How To Implement Synchronous Interactions Between Microservices cannot be reused, because in that case, it is better to:

  • Request Hotel Service to find the list of available hotel rooms.
  • On the specific hotel room selection, call three API asynchronously to receive hotel room summary from Hotel Service, to receive attractions from Hotel Attractions Service and to receive events from Third-Party Events Service. If Hotel Attractions Service or Third-Party Events Service cannot process the requests, empty sections related to this data will be shown on the screen.

For this post, the flight booking system is used.

City and Flight Microservices as an Initial Step to Asynchronous Communications

To begin with, in order to specify the most basic flight details, information about cities is required. As a result, the City Service microservice is created. In the scope of this post, cities are used only for flights. However, cities can be used in other services like Hotel Service, Car Rental Service, Attractions Service, Weather Service, User Service, etc. This service can have a simple CRUD API. The city can be described with name, description, country, population, currency, language, historical events, etc.

Let’s imagine, that for the Flight Service we only need a city id and name to create a flight. Attractions Service probably needs also city description, currency, language, etc.

It is worth mentioning that cities are rarely changing. Another factor that can be considered is the fact that this City Service is used by many other services. Calling each time a City Service with the synchronous approach to get information about a city can generate a huge load on it. And in any case, e.g. in Flight Service, we need to link the cities to a specific flight.

What can be done?

  • Message broker is used e.g. Kafka or RabbitMQ.
  • Each service that requires cities is subscribed to some topic e.g. cities_topic.
  • On each operation (CUD) in City Service an event is created. This event contains city snapshot with all fields and the operation that was performed.
  • This city event is published into the message broker in cities_topic.
  • Each subscribed to this topic service receives an event and saves it into the service’s database for further usage.
  • In one service (e.g. Flight Service) cities table can contain only id and name. In another services, other fields can be saved.
  • It is an example of Publish-Subscribe pattern.

That’s all. We do not need to use City Service in order to work with flights. When City Service is down, Flight Service is not affected. Moreover, Flight Service can be tested independently. We just need to insert data into the Flight Service cities database table.

Making Flight and Notification Microservices Asynchronous

Let’s continue with our example and describe the relations between Flight Service And Notification Service.

When the user books the flight, we want to send the booking details to the user. It can be an email, SMS, push notification to the smartphone application, etc.

The Flight Service is responsible only for flight operations. It should not know about message delivery. Moreover, other services can be interested in sending some user notifications. We do not want to duplicate delivery logic:

  • Find a target user.
  • Find user preferences (e.g. user can disable SMS notifications).
  • Find user contact details e.g. email.
  • Find email template based on some predefined type e.g. Flight Successful Booking.
  • Create an email body.
  • Send an email.
  • Track delivery and make retries.

As a result, Notification Service can be used for such operations.

  • Notification Service is subscribed to a single topic e.g. notifications.
  • Flight Service creates an event about the notification and publishes it to the topic (all services use a single notifications topic).
  • Notification Service is responsible for receiving and sending notifications to the target user.

If Flight Service publishes an event to the notifications topic and Notification Service is done, an event will be saved in a message broker and processed when Notification Service operability is restored.

Summary

In this article, Asynchronous Microservices Interactions were reviewed. This approach helps to make services more independent. However, in some cases, data duplication across services can be an issue. Kafka or RabbitMQ can be used to implement such asynchronous microservices interactions.

Originally published at https://datamify.com on November 17, 2021.

--

--