Skill/spring

Spring WebFlux Mono / Flux

진열사랑 2025. 5. 12. 17:18

Mono ? Flux ?

  Spring WebFlux는 Reactive 스타일의 어플리케이션을 개발 할 수 있게 도와주는 프레임워크이며, Reatvice Stream 을 지원하다고 하였습니다. Spring WebFlux 는 이러한 것을 지원하기 위해서  Reactive F/W로 Reactor 와 RxJava 중 Reactor 프로젝트를 사용하여 Reative 스타일의 어플리케이션을 개발을 도와줍니다. 이러한 스타일로 개발을 하다보면 항상 마주치는 것이 Mono 와 Flux 이며 도대체 이게 무엇인지 이해가 되지 않을 겁니다.

Mono

  공식 문서를 참고 하면 Mono 는 아래와 같이 설명하고 있습니다. Reative Stream Publisher 인데, 0 ~ 1 개의 데이터를 전달한다 이렇게 이해하고 넘어 가겠습니다.

A Reactive Streams Publisher with basic rx operators that emits at most one item via the onNext signal then terminates with an onComplete signal (successful Mono, with or without value), or only emits a single onError signal (failed Mono).

 

 

  위 그림은 Mono 의 동작을 마블 다이어그램으로 나타낸 것이며, 0 또는 1개의 데이터를 처리 한다는 것을 다이어그램으로 나타낸 것입니다.

Flux

  공식 문서를 참고 하면 Flux 는 아래와 같이 설명하고 있습니다. Reative Stream Publisher  구현체 인데, 0 ~ N 개의 데이터를 전달하고 Complete 한다. (성공 또는 에러)

A Reactive Streams Publisher with rx operators that emits 0 to N elements, and then completes (successfully or with an error). The recommended way to learn about the Flux API and discover new operators is through the reference documentation, rather than through this javadoc (as opposed to learning more about individual operators). See the "which operator do I need?" appendix.

  위 그림은 Flux 의 마블다이어그램을 나타내고 있으며, 0 ~ N 개의 데이터를 방출 하며, 데이터를 전달 할때 마다 onNext 이벤트를 발생하고, 데이터 전달이 완료 되면 onComplete 이벤트 그리고 오류가 발생하면 onError 이벤트가 발생 합니다.

 

  Spring WebFlux 는 기본적으로 Tomcat 대신 netty 서버에서 동작 하고 있으며 (Tomcat, Undertow 에서도 가능), Reactor 프로젝트 모듈을 활용하여 Reative 스타일로 개발을 할 수 있게 지원 합니다. 그리고, Reator 의 Publisher 구현체인 Mono 와 Flux 를 이용하여 신호(데이터)를 0 또는 1개, 0 또는 N 개를 전달하여, 클라이언트에 응답 할 수 있게 해줍니다.  Mono와 Flux는 Spring WebFlux의 핵심인 리액티브 프로그래밍 모델에서 사용되는 Reactive Streams 타입입니다.

  실제로 Spring WebFlux 를 통해서 개발을 진행 하다 보면, List 형태는 Flux 를 통해서 핸들링하고, Object 는 Mono 를 통해서 핸들링 하고 있습니다. 물론, Flux 형태를 Mono로 변환하거나, Mono를 Flux 로 변환 할 수 있습니다. 이는 어플리케이션 비지니스로직을 어떻게 구현하는냐에 따라서 적절하게 활용 하면 됩니다.

 

✅ 핵심 차이

타입 설명 예시

Mono<T> 0 또는 1개의 데이터를 비동기적으로 처리함 로그인 결과, 단일 사용자 정보
Flux<T> 0개 이상의 데이터를 스트림(흐름)으로 처리함 목록 조회, 실시간 알림 등

📌 Mono<T> 자세히 보기

✔ 정의

Mono<T>는 "0개 또는 1개의 값"을 비동기적으로 반환하는 리액티브 타입입니다.

✔ 예시

public Mono<User> getUserById(String id) {
    return Mono.just(new User(id, "Alice"));  // 하나의 사용자 반환
}
public Mono<Void> deleteUser(String id) {
    return Mono.empty(); // 아무 것도 반환하지 않음 (0개)
}

📌 Flux<T> 자세히 보기

✔ 정의

Flux<T>는 "0개 이상(무한 가능)"의 값을 비동기적으로 순차적으로 처리하는 타입입니다.

✔ 예시

public Flux<User> getAllUsers() {
    return Flux.just(
        new User("1", "Alice"),
        new User("2", "Bob")
    );
}
public Flux<String> streamWords() {
    return Flux.fromIterable(List.of("Spring", "WebFlux", "Mono", "Flux"));
}

🔁 반환 타입 비교

함수 목적 동기 (MVC) WebFlux 리액티브

단일 값 반환 User Mono<User>
여러 값 반환 List<User> Flux<User>
아무것도 반환 안 함 void Mono<Void>

⚙️ 컨트롤러 예시

@RestController
public class UserController {

    @GetMapping("/user/{id}")
    public Mono<User> getUser(@PathVariable String id) {
        return userService.findUserById(id); // Mono 반환
    }

    @GetMapping("/users")
    public Flux<User> getAllUsers() {
        return userService.findAllUsers(); // Flux 반환
    }
}

⚠️ 주의할 점

  • Mono와 Flux는 실제 데이터가 들어있는 게 아니라 → "데이터가 나중에 도착할 것이다"를 표현하는 Publisher입니다.
  • 값을 꺼내려면 .subscribe(), .block() 등을 호출해야 하지만, WebFlux에서는 프레임워크가 자동으로 구독합니다.
  • block()을 직접 호출하면 논블로킹 철학을 깨트려 WebFlux의 성능 이점을 잃게 됩니다.

✅ 한줄 요약

  • Mono = 0 또는 1개 비동기 값
  • Flux = 0개 이상의 비동기 스트림
    → WebFlux에서 REST API 응답, DB 처리 등 모든 비동기 처리를 이들로 표현합니다.

추가로 원하시면 Mono/Flux의 조합, 변환 (map, flatMap) 등 고급 연산자도 설명드릴 수 있습니다.
다뤄보고 싶으신가요?