자라선

34. Rest Client 본문

Develop/Spring Boot

34. Rest Client

자라선 2020. 7. 27. 17:42

스프링 부트는 Rest 요청을 보낼수 있도록 클라이언트 라이브러리를 제공함

 

테스트 용 RestController 하나와 Handler 2개 예제 생성

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class SampleController {
 
    @GetMapping("/hello")
    public String hello() throws InterruptedException {
        Thread.sleep(5000l);
        return "hello";
    }
 
    @GetMapping("/world")
    public String world() throws InterruptedException {
        Thread.sleep(3000l);
        return "world";
    }
}

RestTemplate

·        Blocking I/O 기반의 Synchronous API

·        RestTemplateAutoConfiguration

·        프로젝트에 spring-web 모듈이 있다면 RestTemplateBuilder 빈으로 등록해 줍니다.

·        https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#rest-client-access

 

RestTemplate 은 동기화 API이며 각 단계에서 실행 후 결과가 반환할때 까지 대기

spring-boot-starter-web 의존성에 이미 RestTemplateAutoConfiguration이 정의 되어 있어서 바로 사용가능

테스트 예제

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.client.RestTemplate;
 
@Order(0)
@Component
public class RestRunner implements ApplicationRunner {
 
    @Autowired
    RestTemplateBuilder builder;
 
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("RestRunner");
 
        RestTemplate restTemplate = builder.build();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
 
        // TODO /hello
        String helloRest = restTemplate.getForObject("http://localhost:8080/hello", String.class);
        System.out.println(helloRest);
 
        // TODO /world
        String worldRest = restTemplate.getForObject("http://localhost:8080/world", String.class);
        System.out.println(worldRest);
 
        stopWatch.stop();
        stopWatch.prettyPrint();
    }
}

WebClient

·        Non-Blocking I/O 기반의 Asynchronous API

·        WebClientAutoConfiguration

·        프로젝트에 spring-webflux 모듈이 있다면 WebClient.Builder 빈으로 등록해 줍니다.

·        https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client

 

 

WebClient 는 비동기 API이며 실행 후 바로 다음 라인으로 넘어감

WebClient 사용하기 위해서는 webflux 의존성이 필요함

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

테스트 예제

Mono 는 stream APi이며 stream을 subscribe 를 실행하기 전에는 실행안함

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
 
@Order(1)
@Component
public class WebRunner implements ApplicationRunner {
 
    @Autowired
    WebClient.Builder builder;
 
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("WebRunner");
 
        WebClient webClient = builder.build();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
 
        // TODO /hello
        Mono<String> helloMono = webClient.get().uri("http://localhost:8080/hello")
                .retrieve()
                .bodyToMono(String.class);
 
        helloMono.subscribe(s -> {
            System.out.println(s);
 
            if(stopWatch.isRunning()){
                stopWatch.stop();
            }
 
            System.out.println(stopWatch.prettyPrint());
            stopWatch.start();
        });
 
        // TODO /world
        Mono<String> worldMono = webClient.get().uri("http://localhost:8080/world")
                .retrieve()
                .bodyToMono(String.class);
 
        worldMono.subscribe(s -> {
            System.out.println(s);
 
            if(stopWatch.isRunning()){
                stopWatch.stop();
            }
 
            System.out.println(stopWatch.prettyPrint());
            stopWatch.start();
        });
 
        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());
    }
}

WebClient Customizer or RestTemplate

모든 WebClient에서 빌더패턴에 동일한 설정을 적용시키기 위해서 @Bean을 사용해  설정이 가능하다.

RestTemplate 도 동일한 RestTemplateCustomizer 객체로 동일하게 설정가능

    @Bean
    public WebClientCustomizer webClientCustomizer(){
        return new WebClientCustomizer() {
            @Override
            public void customize(WebClient.Builder webClientBuilder) {
                webClientBuilder.baseUrl("http://localhost:8080");
            }
        };
    }

 

HttpClient 변경 (RestTemplate)

Java net Http Connection 에서 Apache Http Connection 으로 변경

 

기본 httpClientjava.net.HttpURLConnection 이다.

이것을 Apache Http Connection 으로 변경하기 위해서는 의존성을 정의

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

setRequestFactory Apache HttpClient ClientHttpRequestFactory 의 추상화 타입을 인스턴스로 생성하여 주입

이렇게 스프링은 PSA(Portable Service Abstraction) 가 적용이 되어있고 장점을 볼수 있다.

 

PSA 는 환경의 제약없이 일관된 방식의 기술로 접근 환경을 제공하려는 추상화 구조

쉽게 말해 쉬운 방식으로 내부의 접근 구조에 대해 변경할수 있도록 구조화된 것

    @Bean
    public RestTemplateCustomizer restTemplateCustomizer(){
        return new RestTemplateCustomizer() {
            @Override
            public void customize(RestTemplate restTemplate) {
                restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
            }
        };
    }

 

RestTemplate

·        기본으로 java.net.HttpURLConnection 사용.

·        커스터마이징

o   로컬 커스터마이징

o   글로벌 커스터마이징

·        RestTemplateCustomizer

·        재정의

 

WebClient

·        기본으로 Reactor Netty HTTP 클라이언트 사용.

·        커스터마이징

o   로컬 커스터마이징

o   글로벌 커스터마이징

·        WebClientCustomizer

·        재정의

 

'Develop > Spring Boot' 카테고리의 다른 글

[Spring Boot][Mybatis] Mapper Interface  (0) 2020.07.31
35. Spring Actuator  (0) 2020.07.27
33. Spring Security  (0) 2020.07.27
32. Neo4j Connection  (0) 2020.07.27
31. MongoDB Connection  (0) 2020.07.27
Comments