티스토리 뷰
그동안 잘 사용하고 있던 RestTemplate이 곧 Deprecated가 된다고 한다. 그렇다고 못쓰는건 아니다.
NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward.
Please, consider using the org.springframework.web.reactive.client.WebClient which has a more modern API and supports sync, async, and streaming scenarios.
그러면서 spring docs에서는 WebClient로 바꾸라고 권장을 하고 있다. 하지만 현재 프로젝트의 성격과 WebClient는 좀 맞지 않아서 RestTemplate의 대안인 OpenFeign을 사용하기로 하였다.
Feign이란 Netflix에서 개발한 웹서비스를 편하게 할 수 있도록 지원해주는 기능이다. 믿고 쓰는 Netflix!
기존의 RestTemplate과 비교해보며 Feign으로 어떻게 변환할 수 있을지 살펴보자.
대략적인 시나리오는 A라는 서비스에서 B라는 서비스를 호출을 한다. A서비스에서 oing이라는 메세지를 B에 전달을 해주면 B에서 이를 받아 가공하여 A로 보내주는 아주아주 간단한 시나리오이다.
A Service - RestTemplate version
Controller.java
@PostMapping("/testRestTemplate")
public void testRestTemplate() {
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
bodyMap.add("testValue", "oing");
HttpHeaders headers = new HttpHeaders();
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8772/targetService",
requestEntity, String.class);
System.out.println(response.getBody());
}
기존의 RestTemplate을 사용하는 방법이다. HttpEntity에 필요한 값을 넣고 RestTemplate을 통해 URL과 HttpEntity를 넘겨서 ResponseEntity를 받는 방식이다. 직관적이라 보고 이해하기 쉽다.
A Service - OpenFeign version
OpenFeign을 사용하기 위해서는 몇가지 준비가 필요하다.
1. pom.xml
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.0</spring-cloud.version>
</properties>
... 중략 ...
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
... 중략 ...
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
위와 같이 openfeign을 사용하기 위한 dependency를 추가해야 한다. 한가지 주의할점은 springboot의 version과 spring-cloud의 version을 잘 맞춰줘야 한다. 필자의 경우는 springboot는 2.4.x version을 사용하고 있다.
springboot의 version과 spring-cloud의 version 확인은 여기를 참조하자.
2. Springboot main 클래스에 @EnableFeignClients 추가
@EnableFeignClients
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
3. @FeignClient interface 추가
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "target", url = "http://localhost:8772")
public interface TestFeign {
@PostMapping(value="/targetService")
String sendMessage(@RequestParam("testValue") String testValue);
}
B라는 서비스에 붙기 위한 @FeignClient라는 것을 정의해줘야한다. Feign을 사용하면 이렇게 연결할 서비스별로 이런 interface를 만들어줘야한다. 그리고 B 서비스에 대한 상세 mapping 정보도 이곳에서 정의를 해준다. 이곳에 정의한 메소드명은 A서비스 B서비스 달라도 상관없지만 그외 나머지는 모두 동일하게 작성해줘야 한다.
4. Controller.java
@RestController
public class Test {
@Autowired
private TestFeign testFeign;
@PostMapping("/testFeign")
public void testFeign(HttpServletResponse res) throws IOException {
String result = testFeign.sendMessage("oing");
System.out.println(result);
}
}
@FeignClient interface에 통신을 위한 정의는 다 해놓아서 이 Controller에서는 param만 넣어주면 된다. oing이라는 String Value를 B 서비스로 전달을 완료했다.
B Service (공통)
Controller.java
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TargetController {
@PostMapping(value = "/targetService")
public String targetMethod(@RequestParam("testValue") String testValue){
return testValue + " is pretty";
}
}
RestTemplate으로 보내던 OpenFeign으로 보내던 받는곳은 동일하다. A 서비스로부터 전달받은 oing이라는 값이 testValue에 들어가있을것이고 살을 붙여서 다시 A 서비스로 전달을 해준다.
그럼 A 서비스에서는 이를 전달받아 "oing is pretty" 라는 문구를 출력할 수 있다.
끝!