From RestTemplate to Feign

Lime5005
3 min readDec 6, 2021

I’m currently learning Spring Cloud about MicroService, there is a point for load balance and two ways to implement it.

First, using RestTemplate.

There are these steps:

1, Add to application.yml , (here I have 3 different servers to handle the request: 7001, 7002, and 7003, in case one server is shut down, the others can be served).

server:
port: 80

eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/, http://localhost:7002/eureka/, http://localhost:7003/eureka/

logging:
level:
web: debug

2, Add this bean to config repository:

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

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

3, Using RestTemplate in my controller:

@RestController
public class DeptConsumerController {

@Autowired
private RestTemplate restTemplate;

private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}

@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/" + id, Dept.class);
}

@RequestMapping("consumer/dept/list")
public List<Dept> getAll() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}

}

4, My main class for port 80:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class, args);
}
}

5, Now I can run one of my providers on port 8001, it will bring me its database.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class, args);
}
}

6, At the same time, run my server 7001 as below, my provider 8001 as above, and my client port 80 as mentioned:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class, args);
}
}

I will receive all the data as I defined in my DeptConsumerController from URL: “http://localhost/consumer/dept/list”.

Now we’ll do the same thing in the “Feign” way:

1, Write a DeptClientService.interface in a service repository.

@Service
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")//This is the name defined in the provider module.
public interface DeptClientService {

@GetMapping("/dept/get/{id}")
Dept queryById(@PathVariable("id") Long id);

@GetMapping("/dept/list")
List<Dept> queryAll();

@PostMapping("dept/add")
boolean addDept(Dept dept);
}

2, Then, we need to add the maven dependency:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>

3, Now change the controller as below:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springcloud.pojo.Dept;
import springcloud.service.DeptClientService;

import java.util.List;

@RestController
public class DeptConsumerFeignController {

@Autowired
private DeptClientService service = null;

@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
return service.addDept(dept);
}

@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return service.queryById(id);
}

@RequestMapping("consumer/dept/list")
public List<Dept> getAll() {
return service.queryAll();
}

}

4, Modify the annotation in main class:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"springcloud.service"})//Where you can reach the service interface.
public class FeignDeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(FeignDeptConsumer_80.class, args);
}
}

Keep the other settings the same as before, now run the server, the provider, and the new client port, and you will get the same result.

That’s simple, right? Thanks for reading! 😆

--

--

Lime5005

Web developer, focus on Java, JavaScript, PHP, HTML, CSS.