BackEnd/Spring WebFlux

Spring WebFlux 심화 시리즈 (3) - Flux로 페이징 처리하는 방법

Raconer 2025. 4. 28. 23:27
728x90

Spring WebFlux 심화 시리즈 (3) - Flux로 페이징 처리하는 방법

대량의 콘텐츠를 WebFlux로 스트리밍할 때, 모든 데이터를 한 번에 클라이언트로 보내는 것은 비효율적이다. 특히 데이터가 수천 건 이상일 경우, 반드시 페이징 처리가 필요하다. 이 글에서는 WebFlux 환경에서 Flux를 이용해 페이징 처리하는 방법을 정리한다.


1. 기본 개념

  • 전통적인 MVC에서는 PageRequest를 사용해 DB 쿼리 단계에서 페이징한다.
  • WebFlux에서도 원칙은 같다: DB 쿼리에서 필요한 데이터만 가져와야 한다.
  • Flux를 사용하더라도, 전체 데이터를 Flux로 읽고 나서 자르는 것은 비효율적이다.

2. 실전 예제 (R2DBC 기준)

2.1 ContentService 예시

@Service
class ContentService(private val contentRepository: ContentRepository) {

    fun getContentsByPage(page: Int, size: Int): Flux<Content> {
        val offset = page * size
        return contentRepository.findContentsWithPaging(offset, size)
    }
}

2.2 ContentRepository 예시 (R2DBC Custom Query)

interface ContentRepository : ReactiveCrudRepository<Content, Long> {

    @Query("SELECT * FROM contents LIMIT :size OFFSET :offset")
    fun findContentsWithPaging(offset: Int, size: Int): Flux<Content>
}

2.3 Controller 예시

@RestController
@RequestMapping("/contents")
class ContentController(private val contentService: ContentService) {

    @GetMapping
    fun listContents(@RequestParam page: Int, @RequestParam size: Int): Flux<Content> {
        return contentService.getContentsByPage(page, size)
    }
}

3. 흐름 요약

Client 요청 (page, size) → Controller → Service → Repository (LIMIT OFFSET 쿼리) → Flux<Content> 반환

4. 주의할 점

항목 설명
전체 데이터를 Flux로 받아서 자르는 것은 금지 메모리 낭비 심각, 성능 저하 발생
항상 DB 쿼리 단계에서 페이징 LIMIT, OFFSET 이용
반응형 데이터베이스 드라이버 사용 R2DBC 기반으로 Non-Blocking 쿼리 수행
728x90