Using Feign Client for Microservices Communication | SpringBoot

Prashant KatarePrashant Katare
2 min read

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 →

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 → 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);
    }

}
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.