파란하늘의 지식창고
반응형

webflux로 서비스를 만들어보면서  map과 flatMap을 언제 써야 할지 헷갈릴 때가 있어 공부한 내용을 정리함.


map과 flatMap은 둘 다 스트림의 중간에 값을 변환해주는 역할을 한다.

map은 1 : 1로 반환을 보증하고 flatMap은 1 : N을 변환할 수 있다.

요청에 대해 N개를 병렬로 실행할 경우가 많지 않아 map을 많이 쓸 것 같지만 개발을 하다 보면 대다수의 경우 flatMap을 사용하게 된다.

flatMap을 사용하는 경우

flatMap을 사용하게 되는 경우는 다음과 같다.

Mono<T> -> Mono<U> 또는 Mono<T> -> Flux<U>로 변환이 필요한 경우

map과 flatMap의 설명을 보면 다음과 같다.

Publisher method  
Mono map Transform the item emitted by this Mono by applying a synchronous function to it.
flatMap Transform the item emitted by this Mono asynchronously, returning the value emitted by another Mono (possibly changing the value type).
Flux map Transform the items emitted by this Flux by applying a synchronous function to each item.
flatMap Transform the elements emitted by this Flux asynchronously into Publishers, then flatten these inner publishers into a single Flux through merging, which allow them to interleave

map 은 반환 값이 대상 Object이고 flatMap은 reactor의 Publisher (Mono / Flux)이다.

Mono<T> -> Mono<U>의 flatMap의 경우 성능 상 이점이 아닌 Publisher 객체 타입 변환이 목적이기 때문에 flatMap을 사용한다.

Mono<T> -> Flux<U>의 flatMap의 경우 Publisher 객체 타입도 변환하고 변환된 이후 비동기로 병렬 동작하는 publisher를 사용하는 경우 forEach를 통한 동기로 실행하는 경우보다 빠른 처리가 가능해진다.

Mono<T> -> Mono<T>의 flatMap의 경우 비동기로 처리하는 의미가 없기 때문에 굳이 flatMap을 쓸 이유는 없다.

Flux<T> -> Flux<T> 또는 Flux<T> -> Flux<U>인 경우

Mono와 달리 Flux는 N개를 비동기로 병렬 동작하는 publisher를 사용하는 경우 성능 상 이점이 많기 때문에 되도록 map을 쓰지 않는 게 좋다.

method를 호출하는 경우

어차피 reactive한 개발을 하면 사용하는 모든 method의 반환은 Publisher 형태가 된다.

이렇게 반환된 결과값을 이어 사용해야 하는 경우는 map을 쓰지 않고 flatMap을 쓰는 게 자연스럽게 이어진다.

이 경우 때문에 Mono<T> -> Mono<T>의 경우에도 flatMap을 쓰게 된다.

return value가 Object인 경우

reactive를 사용하면 기존 처럼 Object의 경우 반환 값으로 null을 반환받아 reactive flow내에서 사용할 수 없다.

null이 반환되면 reactive flow가 중지되기 때문에 Mono.empty(), Flux.empty()와 같이 지정된 빈 값 반환 처리를 해야 한다.

이 경우 map을 사용하면 reactive의 빈 객체 반환 정의를 할 수 없게 되기 때문에 flatMap을 사용한다.


결국 위에 열거한 이런저런 이유로 인해 대부분의 경우 flatMap을 사용하게 되지만 무조건 flatMap을 써야 한다가 아닌 위와 같은 이유로 flatMap을 쓰게 된다는 점을 이해하고 개발하는 게 좋을 것 같다.

반응형
profile

파란하늘의 지식창고

@Bluesky_

내용이 유익했다면 광고 배너를 클릭 해주세요