Spring

WebClient 사용할때 주의 (7편)

ybs 2022. 3. 7. 18:59
반응형

webClient 사용할 때 주의사항까진 아니지만 리스트 형태의 response body 를 받는 방법에 대해서 간단히 정리했다. 가끔 Mono<List<T>> 형태로 리턴 webClient 코드를 볼 때가 있다. flatMapIterable 메서드로 Flux 를 사용하는게 좋다.

public Flux<String> getData() {
	return this.webClient.get()
		.uri(uriBuilder -> uriBuilder
			.path("/data")
			.build()
		)
		.retrieve()
		.bodyToMono(DataApiResponse.class)
		.flatMapIterable(DataApiResponse::getContent);
}

@Value
public class DataApiResponse {
	List<String> content;
}

 

getData 를 사용하는 쪽에서는 아래와 같이 Flux 를 toStream 으로 변환 후 List로 변환하면 된다.

List<String> data = apiClient.getData()
	.toStream()
	.collect(toUnmodifiableList());

 


내용 업데이트(2023.12.16)

위의 getData 코드는 DataApiResponse 안에 있는 List 객체 content 를 Flux 로 변환해 리턴시키는 방법을 보여준다.

하지만 만약 DataApiResponse 자체가 List 로 오게 되면 bodyToFlux 를 사용해서 Flux 로 리턴하면 된다.

public Flux<DataApiResponse> getData() {
	return this.webClient.get()
		.uri(uriBuilder -> uriBuilder
			.path("/data")
			.build()
		)
		.retrieve()
		.bodyToFlux(DataApiResponse.class);
}

@Value
public class DataApiResponse {
	String id;
	String name;
}

 

bodyToMono 를 사용한다면 ParameterizedTypeReference 를 활용해 Mono<List<T>> 형태로 리턴 시킬 수도 있는데, 이 방법보단 bodyToFlux 를 이용해 Flux 로 리턴하는게 더 적합해보인다.

public Mono<List<DataApiResponse>> getData() {
	return this.webClient.get()
		.uri(uriBuilder -> uriBuilder
			.path("/data")
			.build()
		)
		.retrieve()
		.bodyToMono(new ParameterizedTypeReference<List<DataApiResponse>>() {});
}

@Value
public class DataApiResponse {
	String id;
	String name;
}

 

그런데 Mono<List<T>> 형태로 리턴시키는게 더 합리적인 경우도 경험했다. getData 로 얻은 결과를 그대로 다른 apiClient request body 로 전달한다면 굳이 Flux 로 변환할 이유가 없었다.

public void test() {
  Mono<List<DataApiResponse>> data = apiClient.getData();
  
  data.flatMap(it -> // it 은 List<DataApiResponse> data
    apiClient.getMember(it) // 새로운 apiClient request body 에 List 자체를 넘김
  );
}

public Mono<List<DataApiResponse>> getData() {
	return this.webClient.get()
		.uri(uriBuilder -> uriBuilder
			.path("/data")
			.build()
		)
		.retrieve()
		.bodyToMono(new ParameterizedTypeReference<List<DataApiResponse>>() {});
}

 

 

반응형