Using Rest Template for Microservices Communication | SpringBoot

Prashant KatarePrashant Katare
3 min read

In this article we will learnt to make Http call using RestTemplate from one microservice to another microservice api and consume data.

We have 3 microservices for our Hotel Rating Application →

We already have setup our Discover server and above 3 microservices and Discovery Client for out Hotel Rating Application. Check out these articles for recap -

To achieve microservices communication we will make call from UserService to RatingService microservice api to get list of rating for a particular user using the user id of that user. This is how our microservices will communicate.

Step 1 → Creating a RestTemplate Bean. There are two ways to do this (Use either A or B) -

  • ( A ) Declare the bean inside the main method of our Application class.
package com.movie_rating.user.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;

@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

}
  • ( B ) Create the bean inside the config class.
package com.movie_rating.user.service.config;

import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;

@Configuration
public class AppConfig {

       @Bean
       @LoadBalanced
       public RestTemplate restTemplateBean() {
            return new RestTemplate();
        }
}

Here @LoadBalanced annotation does a few important things for us. It enables Load Balancing for our application in case multiple instances of a microservices are running. Also it allows us to not hard code the Api url when we make call to Api through RestTemplate.

So, “http://localhost:8083/ratings/users/{userID}“ becomes “http://RATINGSERVICE/ratings/users/{userId}”. We don’t need to mention the hostname and port number in our Api url when we make call to Api through RestTemplate, both hostname and port number are replaced with name of the microservice (The name should be same as that appears on Discovery Server under the Applications column).

This also gives us the flexibility to run our microservices to run on any hostname or port number because we don’t need to specify then in the url anymore, since the url isn’t hardcoded.

Step 2 → Autowire the RestTemplate bean and use it to make call to the RatingService Api (http://RATINGSERVICE/ratings/users/{userId}) -

package com.movie_rating.user.service.controllers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.movie_rating.user.service.entities.Rating;
import com.movie_rating.user.service.entities.UserEntity;
import com.movie_rating.user.service.services.UserService;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping
    public ResponseEntity<UserEntity> createtUser (@RequestBody UserEntity user){
        UserEntity tempUser = userService.saveUSer(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(tempUser);
    }

    @GetMapping("{userId}")
    public ResponseEntity<UserEntity> getUser (@PathVariable String userId){
        UserEntity tempUser = userService.getUser(userId);

        ArrayList<Rating> ratings = restTemplate.getForObject("http://RATINGSERVICE/ratings/users/"+userId, ArrayList.class);
        tempUser.setRatings(ratings);
        return ResponseEntity.ok(tempUser);
    }

    @GetMapping
    public ResponseEntity<List<UserEntity>> getAllUser (){
        List<UserEntity> allUser = userService.getAllUser();
        return ResponseEntity.ok(allUser);
    }

}
0
Subscribe to my newsletter

Read articles from Prashant Katare directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Prashant Katare
Prashant Katare

Experienced Spring Boot Developer with over 3+ years of expertise in developing scalable and high-performance web applications and microservices. Proficient in Java and Spring Boot frameworks, with hands- on experience in RESTful APIs and Microservices architecture. Adept at building secure, database-driven applications and integrating various third- party services. Strong problem-solving skills with a focus on delivering clean, maintainable, and efficient code.