728x90
RestTemplate
@SpringBootApplication
public class RestApplication {
@Bean
public ApplicationRunner init(ErApi api) {
return args -> {
//https://open.er-api.com/v6/latest
RestTemplate rt = new RestTemplate();
/*
String res = rt.getForObject("https://open.er-api.com/v6/latest", String.class);
System.out.println(res);
*/
Map<String, Map<String, Double>> res = rt.getForObject("https://open.er-api.com/v6/latest",
Map.class);
System.out.println(res.get("rates").get("KRW")); //header 를 넣거나 post 방식 요청이 힘들다.
};
}
public static void main(String[] args) {
SpringApplication.run(RestApplication.class, args);
}
}
- RestTemplate 같은 경우, getForObject 메서드를 사용하면 API 통신이 가능하다.
- 1번째 파라미터에는 URI
- 2번째 파라미터에는 반환받을 Class 타입 -> 보통은 DTO를 만들어서 반환받는다.
- 3번째 파라미터에는 전달할 UriValue를 작성한다(현재는 없다.)
- 매우 간단하게 사용 가능하며, Reactive 스타일을 사용하지 않고, get 방식으로 가지고 올 거면 RestTemplate를 사용하여도 된다.
WebClient
@SpringBootApplication
public class RestApplication {
@Bean
public ApplicationRunner init(ErApi api) {
return args -> {
WebClient client = WebClient.create("https://open.er-api.com");
Map<String, Map<String, Double>> res2 = client.get().uri("/v6/latest").retrieve()
.bodyToMono(Map.class).block();
System.out.println(res2.get("rates").get("KRW"));
};
}
public static void main(String[] args) {
SpringApplication.run(RestApplication.class, args);
}
}
- WebClient 방식을 사용하면, Reactive 한 형식으로 API를 호출할 수 있다(Mono, Flux 타입으로 반환)
- 비동기 호출이 가능하지만 현재는 동기식으로 block()을 사용하였다.
- RestTemplate 보다 모던하게 API를 작성할 수 있다.
- 자동완성 기능을 통해 좀 더 모던하게 API 호출을 할 수 있다
- Header을 값 세팅이 RestTemplate보다 간편하다.
- Post, Put 등 다양한 메서드를 보다 간편하게 호출할 수 있다.
- 내 Application이 Reactive 방식으로 작성을 하였다면..? WebClient를 사용하자
HTTP Interface
RestApplication
@SpringBootApplication
public class RestApplication {
@Bean
public ApplicationRunner init(ErApi api) {
return args -> {
HttpServiceProxyFactory httpServiceProxyFactory = HttpServiceProxyFactory.builder(
WebClientAdapter.forClient(client))
.build();
ErApi erApi = httpServiceProxyFactory.createClient(ErApi.class);
Map<String, Map<String, Double>> res3 = erApi.getLatest();
System.out.println(res3.get("rates").get("KRW"));
Map<String, Map<String, Double>> res4 = erApi.getLatest();
System.out.println(res4.get("rates").get("KRW"));
};
}
public interface ErApi {
@GetExchange("/v6/latest")
Map getLatest();
}
public static void main(String[] args) {
SpringApplication.run(RestApplication.class, args);
}
}
RestConfiguration
@Configuration
public class RestConfiguration {
@Bean
public ErApi erApi(){
WebClient client = WebClient.create("https://open.er-api.com");
HttpServiceProxyFactory httpServiceProxyFactory = HttpServiceProxyFactory.builder(
WebClientAdapter.forClient(client))
.build();
return httpServiceProxyFactory.createClient(ErApi.class);
}
}
- interface를 정의하고, 어노테이션을 다는 방식으로 작성한다.
- 아직 해당 Interface를 구현하여, 빈으로 등록하는 부분은 수동으로 해야 한다 -> 조만간 Spring에서 이를 자동화하지 않을까 예상된다.
- 인터페이스를 구현한 객체를 Bean으로 등록만 해준다면?? 클라이언트(사용자)는 내부적으로 어떻게 동작하는지 알 필요 없이, bean만 주입받아 사용하면 된다
- feign을 사용하고 있다면 변경을 고려해 볼 만도 하다.
- @RequestHeader, @RequestBody 어노테이션을 조합하여 header, body 값을 전달하면 된다
- 오류 핸들링 같은 경우 WebClient 같은 경우 4xx, 5xx 에러는 WebClientResponseException을 반환하는데, 이를 핸들링 하여 오류를 처리하면 된다.
https://docs.spring.io/spring-framework/reference/integration/rest-clients.html#rest-http-interface
REST Clients :: Spring Framework
WebClient is a non-blocking, reactive client to perform HTTP requests. It was introduced in 5.0 and offers an alternative to the RestTemplate, with support for synchronous, asynchronous, and streaming scenarios. WebClient supports the following: Non-blocki
docs.spring.io
728x90
'Toby의 ReactiveProgramming' 카테고리의 다른 글
| Flux의 특징과 활용방법 (0) | 2022.08.30 |
|---|---|
| Mono의 동작방식과 block() (0) | 2022.08.28 |
| WebFlux (0) | 2022.08.28 |
| CompletableFuture (0) | 2022.08.27 |
| AsyncRestTemplate의 콜백 헬과 중복 작업 문제 (0) | 2022.08.26 |