본문 바로가기
Programing/Java & Spring

WebFlux, WebClient 사용하여 API 호출 - 2편

by 슈퍼와이비 2023. 9. 26.
반응형

📌 JSON 테스트를 위한 사이트 소개

  1. JSON을 사용하는 서비스를 테스트하기 위한 플랫폼입니다.
  2. callback과 같은 여러 매개변수를 지원하여 JavaScript 및 기타 웹 애플리케이션을 테스트할 수 있습니다.
  3. 가장 단순한 http://ip.jsontest.com 라는 API로 IP 주소를 응답받아보도록 하겠습니다.
  4. 브라우저를 열고 http://ip.jsontest.com 을 입력하시면 JSON형태의 데이터가 오는 것을 확인할 수 있습니다.
{
    "ip": "000.000.000.00"
}

 

📌 WebClient를 통해 API 호출하기

✏️ 1편에서 만들었던 WebClient Build에 관한 부분을 메소드로 분리합니다.

private static WebClient getWebClient() throws SSLException {
		ConnectionProvider provider = ConnectionProvider.builder("custom-provider")
				.maxConnections(20)
				.maxIdleTime(Duration.ofSeconds(58))
				.maxLifeTime(Duration.ofSeconds(58))
				.pendingAcquireTimeout(Duration.ofSeconds(60))
				.pendingAcquireMaxCount(-1)
				.evictInBackground(Duration.ofSeconds(30))
				.lifo()
				.build();
		
		SslContext sslContext = SslContextBuilder
				.forClient()
				.trustManager(InsecureTrustManagerFactory.INSTANCE)
				.build();
		
		WebClient client = WebClient.builder()
				.clientConnector(
					new ReactorClientHttpConnector(
							HttpClient.create(provider)
							.secure(t -> t.sslContext(sslContext))
							.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 20000)
							.doOnConnected(
									conn -> conn.addHandlerLast(new ReadTimeoutHandler(30))  //sec
									.addHandlerLast(new WriteTimeoutHandler(60)) //sec
									)
							.responseTimeout(Duration.ofSeconds(60))
							))
				.build();
		return client;
	}

 

✏️ WebClient로 API를 호출합니다.

WebClient webClient = getWebClient();
		
String res = 
        webClient.mutate()
            .build().method(HttpMethod.GET)
            .uri("http://ip.jsontest.com")
            .headers(httpHeaders -> { httpHeaders.set("Content-Type", "application/json");})
            .retrieve()
            .bodyToMono(String.class)
            .block();

System.out.println(res);

 

🔍 소스 코드를 들여다 보도록 하겠습니다.

  1. mutate() 메소드를 호출하여 원래 WebClient 인스턴스를 변경하지 않고 복제한 새로운 WebClient 빌더를 생성합니다.
  2. build() 메소드는 WebClient 빌더를 사용하여 새로운 WebClient 인스턴스를 구성하고 생성합니다.
  3. method(HttpMethod.GET): HTTP 요청 메소드를 설정하는 부분입니다. 이 경우 GET 요청을 보내고 있습니다.
  4. uri("http://ip.jsontest.com"): 요청할 URL을 설정합니다. 이 예제에서는 "http://ip.jsontest.com"로 요청을 보내고 있습니다.
  5. headers(httpHeaders -> { httpHeaders.set("Content-Type", "application/json"); }): HTTP 요청 헤더를 설정합니다. 이 경우 "Content-Type" 헤더를 "application/json"으로 설정하고 있습니다. 이렇게 함으로써 서버에게 요청이 JSON 형식의 데이터를 기대한다고 알립니다.
  6. retrieve(): 실제 HTTP 요청을 보내고 응답을 받기 위한 단계입니다. 이 메소드는 Mono<ClientResponse>를 반환합니다.
  7. bodyToMono(String.class): 서버로부터 받은 응답을 Mono 스트림으로 변환하는 부분입니다. 이 경우 응답이 문자열로 예상되므로 String.class를 사용하여 문자열로 변환하고 있습니다.
  8. block(): Mono<String>을 동기적으로 블로킹하여 실제 HTTP 요청을 보내고 응답을 기다립니다. 이 코드는 결과 문자열을 res 변수에 할당합니다.

 

응답받은 res값을 로그로 출력해보면 브라우저에서 요청한것과 동일한 JSON 응답값이 온 것을 확인할 수 있습니다. 그렇지만 이 코드에는 개선이 필요한 부분이 있습니다.

 

  • block() 메소드는 Mono 또는 Flux 스트림을 동기적으로 블로킹하고 결과를 기다리는 데 사용됩니다. 
  • 이것은 리액티브 프로그래밍의 원칙을 어겼으며, 일반적으로 리액티브 스트림을 사용하는 Spring WebClient의 사용 방식과는 다릅니다.
  • 리액티브 프로그래밍의 핵심 아이디어는 비동기적인 방식으로 작업을 수행하고 결과를 기다리지 않고 다른 작업을 수행하는 동안 리소스를 효율적으로 활용하는 것입니다.
  • block() 메소드를 사용하면 비동기 코드를 동기 코드로 변환하고, 이로 인해 웹 애플리케이션의 확장성과 효율성에 부정적인 영향을 미칠 수 있습니다.
  • Spring WebClient를 최대한 활용하려면 리액티브 스트림을 사용하고, subscribe() 메소드를 사용하여 비동기적인 방식으로 결과를 처리하는 것이 권장됩니다. 이렇게 하면 응답을 기다리지 않고 다른 작업을 수행하면서 리액티브 프로그래밍의 이점을 누릴 수 있습니다.

 

📌 3편 - subscribe() 를 사용하여 비동기적 방식으로 처리하기

WebFlux, WebClient 사용하여 API 호출 - 3편 (tistory.com)

 

WebFlux, WebClient 사용하여 API 호출 - 3편

📌 subscribe() 를 사용하여 비동기적 방식으로 처리하기 앞서 봤던 block() 메소드는 Mono 또는 Flux 스트림을 동기적으로 블로킹하고 결과를 기다리는 데 사용됩니다. 리액티브 프로그래밍의 핵심 아

whybk.tistory.com

 

반응형