Using Feign Client for Microservices Communication | SpringBoot
In this article we will learnt to make Http call using Feign Client from one microservice to another microservice api and consume data.
We have 3 microservices for our Hotel Rating Application →
UserService - localhost:8081/users
HotelService - localhost:8082/hotels
RatingService - localhost:8083/ratings
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 -
Implementing Discovery Server in SpringBoot | Service Discovery | Microservices
Implementing Service Discovery Client in SpringBoot | Microservices
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 → Add dependency.
- OpenFeign | SPRING CLOUD ROUTING
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Step 2 → Add @EnableFeignClients to the Application class of our project which has the main method.
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.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
Step 3 → Create HotelService interface using Feign Client and declare the method to call the api. We only need to declare the methods inside our HotelService interface and do not need to create an implementation class to override the methods. Feign Client will do that for us. We simply can now use the HotelService to make Http api call to HotelService microservice api.
package com.movie_rating.user.service.services;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.movie_rating.user.service.entities.Hotel;
@FeignClient(name="HOTELSERVICE")
public interface HotelService {
@GetMapping("/hotels/{hotelId}")
Hotel getHotel(@PathVariable String hotelId);
}
Step 4 → Call the HotelService api and consume the data (check method “getUser “).
package com.movie_rating.user.service.controllers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
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.Hotel;
import com.movie_rating.user.service.entities.Rating;
import com.movie_rating.user.service.entities.UserEntity;
import com.movie_rating.user.service.services.HotelService;
import com.movie_rating.user.service.services.RatingService;
import com.movie_rating.user.service.services.UserService;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private HotelService hotelService;
@Autowired
private RatingService ratingService;
@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);
Rating [] ratings = ratingService.getAllRatings(userId);
List<Rating> allRatings = Arrays.stream(ratings).toList();
List<Rating> ratingsList = allRatings.stream().map(rating -> {
Hotel hotel = hotelService.getHotel(rating.getHotelId());
rating.setHotel(hotel);
return rating;
}).collect(Collectors.toList());
tempUser.setRatings(ratingsList);
return ResponseEntity.ok(tempUser);
}
@GetMapping
public ResponseEntity<List<UserEntity>> getAllUser (){
List<UserEntity> allUser = userService.getAllUser();
return ResponseEntity.ok(allUser);
}
}
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.