Different Ways to Establish Communication Between Spring Microservices
If you are working with a Spring Boot project which involves multiple microservices, You might have felt the need to communicate from microservice m1 to microservice m2. Depending upon business use-cases, this communication can be of synchronous or asynchronous type. Before digging dip further. Let’s understand the use-case first. There are two microservices:
- Restaurant-Service: Responsible for maintaining items being served by a restaurant, processing orders, etc.
- User-Service: Responsible for maintaining user details.
Now suppose a user visits a restaurant’s page, selects some cuisine of his choice and clicks on the “Place Order” button. When this request lands in restaurant-service, the service would want to validate user details before processing this order. But our user details lie under user-service. Hence here comes the need to communicate from restaurant-service to user-service. Synchronous communication of m2 from m1 is like calling an API of m2 directly from m1.
Synchronous Way
When we talk about synchronous communication, there could be two ways:
- REST Template
- Feign
REST Template
REST Template is the easiest way to establish synchronous communication from m1 to m2. RestTemplate is a class available under spring.framework.web.client that acts as a synchronous client to perform HTTP requests. In the below example, we have used getForEntity method that accepts complete URL of the user-service that we want to invoke, followed by Data-Object class name which that URL is supposed to return, and a map. If the provided userId is not valid, the API call would throw a custom exception which we are handing on the restaurant-service side.
Java
HashMap<String, Long> params = new HashMap<>(); params.put( "userId" , orderDetails.getUserId()); try { ResponseEntity<User> response = new RestTemplate().getForEntity( "http://localhost:8080/users/{userId}" , User. class , params); } catch (Exception ex) { throw new InvalidUserIdException( "User Id " + orderDetails.getUserId() + " Not Found" ); } |
Feign
Feign requires additional configuration across both services if you want to go by this way. This approach uses standard Java interfaces. Addition perks of using feign over rest-template is that you don’t get to hard-code your URL here. Eureka Client ID can also be used for server-discovery purposes in order to establish communication.
Asynchronous Way
One possible asynchronous way to establish communication is by using a message broker. Let’s understand the use-case first.
Considering the microservices discussed above, let’s suppose a user has placed his order. Now the order would go under various stages like Accepted, Preparation-Started, Ready-To-Pick, Delivered. Assuming all the stages of the order would be updated by the restaurant-service, we want to notify user-service every time the order-status is updated. Now this can be achieved either way but the asynchronous way would be more convenient here.
- Message-Broker: It behaves as an intermediary service between m1 and m2. When m1 has to communicate with m2, m1 would push a message to the broker instead of directly sending it to the m2. Depending on the broker’s type (ActiveMQ and Kafka are two popular message-brokers but they have different approaches of communication), the message will be conveyed to the listener of m2 and action would be taken accordingly. Here m1 would be known as producer while m2 would be known as consumer.
Contact Us