-
Reactor List가 비어있을 때의 switchIfEmpty와 defaultIfEmptySpring/Spring 2021. 10. 14. 11:47
Reactor 에서 Mono나 Flux가 비어 있는 경우 대체 값을 제공하는 switchIfEmpty와 defaultIfEmpty 연산자는 매우 유용하다. 이 글에서는 이 두 연산자의 차이점과 사용 예제, 그리고 이를 통해 얻을 수 있는 장점을 살펴보자.
switchIfEmpty와 defaultIfEmpty의 차이점
switchIfEmpty
switchIfEmpty는 원래 Mono나 Flux가 비어 있을 때 (즉, Mono.empty()나 Flux.empty()인 경우) 대체 Mono나 Flux를 제공하는 연산자이다. 이는 데이터 스트림이 비어 있는 상황에서 다른 데이터 소스로 대체할 때 유용하다.
fun getKeywords(info: String, key: String): Mono<List<String>> { return if (key.isEmpty()) { Mono.empty() // 비어 있는 Mono 반환 } else { Mono.just(listOf(key)) } } val keywords = getKeywords("info", "") .switchIfEmpty(getKeywords("info", "convertedKey")) .onErrorResume { Mono.just(listOf()) } keywords.subscribe { result -> println("Keywords: $result") }
위 코드에서 getKeywords가 Mono.empty()를 반환하면 switchIfEmpty가 실행되어 convertedKey를 사용하는 대체 Mono가 호출된다.
위 마블 다이어그램에서, 원래의 Mono가 비어 있을 경우 대체 Mono로 전환되는 과정을 보여준다.
defaultIfEmpty
defaultIfEmpty는 원래 Mono나 Flux가 실제 값으로 비어 있는 경우, 예를 들어 Mono.just(emptyList())와 같이 빈 리스트를 포함하는 경우에 대체 값을 제공하는 연산자이다. 이는 데이터가 비어 있을 때 기본값을 설정할 때 유용하다.
fun getKeywords(info: String, key: String): Mono<List<String>> { return if (key.isEmpty()) { Mono.just(emptyList()) // 빈 리스트를 포함하는 Mono 반환 } else { Mono.just(listOf(key)) } } val keywords = getKeywords("info", "") .defaultIfEmpty(listOf("defaultValue")) .onErrorResume { Mono.just(listOf()) } keywords.subscribe { result -> println("Keywords: $result") }
위 코드에서 getKeywords가 Mono.just(emptyList())를 반환하면 defaultIfEmpty가 실행되어 Mono.just(listOf("defaultValue"))를 반환한다.
Reactor의 비어 있는 리스트 처리
Reactor에서는 Mono와 Flux를 사용하여 비동기적인 데이터 스트림을 처리할 수 있다. 이때 데이터가 비어 있을 수 있는 상황을 처리하는 것은 중요하다. switchIfEmpty와 defaultIfEmpty를 적절히 사용하면 이러한 상황에서 보다 유연하고 안정적인 코드를 작성할 수 있다.
switchIfEmpty와 defaultIfEmpty의 혼용 사용 방지
이 두 연산자는 비슷해 보이지만, 각각의 목적이 다르다. switchIfEmpty는 원래 스트림이 완전히 비어 있을 때 (즉, Mono.empty()나 Flux.empty()일 때) 사용되고, defaultIfEmpty는 스트림이 실제 값으로 비어 있을 때 (예: Mono.just(emptyList())) 사용된다. 따라서, 리스트가 비어 있는 경우 switchIfEmpty를 사용하는 것은 적절하지 않다.
val keywords = getKeywords("info", "") .switchIfEmpty(Mono.just(listOf("defaultValue"))) // 잘못된 사용
이 경우 getKeywords가 Mono.just(emptyList())를 반환해도 switchIfEmpty가 실행되지 않기 때문에, 예상한 대로 동작하지 않는다.
실용적인 사용 사례
- API 호출 시 대체 데이터 소스 제공:
- 메인 API 호출이 실패하거나 결과가 비어 있을 때 백업 API를 호출하여 대체 데이터를 제공할 수 있다.
- 기본값 설정:
- 데이터베이스 조회 결과가 비어 있을 때 기본값을 설정하여 애플리케이션이 예상치 못한 NullPointerException을 방지할 수 있다.
- 캐시 메커니즘:
- 캐시된 데이터가 없을 때, 원본 데이터 소스를 호출하고 그 결과를 캐시에 저장하는 방식으로 사용할 수 있다.
switchIfEmpty는 원래 스트림이 완전히 비어 있을 때 대체 스트림을 제공하며, defaultIfEmpty는 스트림이 실제 값으로 비어 있을 때 기본값을 설정한다. 이 두 연산자를 적절히 사용하면 비동기 데이터 처리에서 더욱 안정적이고 유연한 코드를 작성할 수 있다. 상황에 맞게 이 연산자들을 활용하여 효율적인 비동기 프로그램을 작성해보자.
'Spring > Spring' 카테고리의 다른 글
Spring Batch 3.0 이상에서 JPA 사용시 PlatformTransactionManager 설정 (0) 2023.06.01 SubscribeOn , PublishOn (31) 2021.12.23 스프링 @Transactional과 잠금 (0) 2021.08.11 Mono.just()와 Mono.defer()에 대한 이해 (0) 2021.07.30 1주차 스프링 스터디 (0) 2021.04.19 - API 호출 시 대체 데이터 소스 제공: