Files
spring-boot-examples/docs/webflux/05_웹플럭스에서 라우팅 처리.md
2025-04-08 19:56:24 +09:00

7.0 KiB

아래는 **"스프링부트 웹플럭스 시리즈"**의 **5장: 웹플럭스에서 라우팅 처리"**에 대한 초안입니다. 4장의 흐름을 이어가며 웹플럭스의 두 가지 라우팅 방식(함수형 라우팅과 어노테이션 기반 컨트롤러)을 비교하고, 실습 예제를 간략히 포함했습니다. 초보자가 이해하기 쉽도록 단계별로 설명하며 자연스러운 문체를 유지했습니다.


5. 웹플럭스에서 라우팅 처리

지난 장에서 MonoFlux로 리액티브 스트림의 기본을 익혔습니다. 이제 이 스트림을 클라이언트 요청에 연결하는 방법을 배워볼 차례입니다. 웹플럭스에서는 라우팅을 처리하는 두 가지 주요 방식이 있습니다: **함수형 라우팅(RouterFunction)**과 어노테이션 기반 컨트롤러. 이번 장에서는 두 접근법을 살펴보고, 각각의 장단점을 비교하며 간단한 예제를 작성해보겠습니다. 자, 시작합시다!

RouterFunction을 사용한 함수형 라우팅

웹플럭스는 함수형 프로그래밍 스타일을 지원하며, RouterFunction을 통해 라우팅을 정의할 수 있습니다. 이 방식은 선언적으로 경로와 핸들러를 연결하며, 코드가 간결하고 유연하다는 장점이 있습니다. 전통적인 컨트롤러보다 더 리액티브 철학에 가까운 접근법이죠.

먼저, 3장에서 만든 프로젝트에 새로운 클래스를 추가합니다. src/main/java/com/example/demo 경로에 RouteConfig 클래스를 만들고 아래 코드를 작성해보세요:

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@Configuration
public class RouteConfig {

    @Bean
    public RouterFunction<ServerResponse> routes() {
        return route(GET("/functional/hello"),
                request -> ServerResponse.ok().bodyValue("Hello from RouterFunction!"));
    }
}
  • @Configuration: 스프링 설정 클래스임을 나타냅니다.
  • RouterFunction<ServerResponse>: 요청 경로와 응답을 정의합니다.
  • route(): /functional/hello로 들어오는 GET 요청에 대해 "Hello from RouterFunction!"를 반환합니다.

애플리케이션을 실행하고 http://localhost:8080/functional/hello로 접속해보세요. 간단한 문자열 응답이 표시될 겁니다. 이 방식은 컨트롤러 클래스 없이도 라우팅을 처리할 수 있어, 코드 구조를 간소화할 수 있습니다.

어노테이션 기반 컨트롤러와의 비교

4장에서 사용했던 어노테이션 기반 컨트롤러는 스프링 MVC와 비슷한 방식으로 동작합니다. @RestController, @GetMapping 같은 어노테이션을 사용해 직관적으로 엔드포인트를 정의하죠. 비교를 위해 이전 예제를 다시 보겠습니다:

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public Mono<String> sayHello() {
        return Mono.just("Hello, WebFlux!");
    }
}

이제 두 방식의 차이를 표로 정리해보겠습니다:

특징 어노테이션 기반 컨트롤러 RouterFunction (함수형)
문법 @GetMapping, @PostMapping route(), GET(), POST()
구조 클래스와 메서드 중심 함수와 람다 중심
익숙함 MVC 경험자라면 쉽게 적응 함수형 프로그래밍에 익숙해야 함
유연성 정해진 구조로 간단히 작성 동적 라우팅이나 조건부 처리에 강점
용도 전통적인 REST API에 적합 리액티브 철학을 살린 경량 애플리케이션

어노테이션 방식은 익숙하고 직관적이어서 초보자에게 추천할 만합니다. 반면, 함수형 라우팅은 더 가볍고 유연하며, 대규모 프로젝트에서 라우팅 로직을 한 곳에 모아 관리하기 좋습니다.

요청 처리와 응답 생성 실습

함수형 라우팅으로 조금 더 실습해보죠. 이번엔 요청 파라미터를 받아 응답을 만들어봅시다. RouteConfig에 새 경로를 추가합니다:

@Bean
public RouterFunction<ServerResponse> routes() {
    return route(GET("/functional/greet/{name}"),
            request -> {
                String name = request.pathVariable("name");
                return ServerResponse.ok().bodyValue("Hello, " + name + "!");
            })
        .andRoute(GET("/functional/hello"),
            request -> ServerResponse.ok().bodyValue("Hello from RouterFunction!"));
}
  • /functional/greet/{name}: URL 경로에서 name 변수를 추출해 맞춤형 인사말을 반환합니다.

http://localhost:8080/functional/greet/Alice로 접속하면 "Hello, Alice!"가 출력됩니다. 이렇게 함수형 라우팅은 요청 데이터를 쉽게 처리하고, MonoFlux로 응답을 확장할 수도 있습니다.

어노테이션 방식으로 동일한 기능을 구현한다면:

@GetMapping("/greet/{name}")
public Mono<String> greet(@PathVariable String name) {
    return Mono.just("Hello, " + name + "!");
}

두 방식 모두 결과는 같지만, 코드 스타일과 구조에서 차이가 느껴지죠?

어떤 걸 선택해야 할까?

  • 어노테이션 기반: 팀이 MVC에 익숙하거나, 빠르게 REST API를 만들고 싶을 때.
  • 함수형 라우팅: 리액티브의 장점을 극대화하거나, 경량화된 라우팅 로직이 필요할 때.

프로젝트 성격과 팀의 선호도에 따라 선택하면 됩니다. 처음엔 어노테이션 방식으로 시작해, 익숙해지면 함수형으로 넘어가보는 것도 좋은 전략입니다.

마무리

이번 장에서 웹플럭스의 라우팅 방식을 두 가지 맛으로 경험해봤습니다. 어노테이션 기반은 친숙하고, 함수형은 새롭고 강력하죠. 다음 장에서는 리액티브 데이터베이스와의 연동을 다루며, 웹플럭스의 실무적인 면모를 더 깊이 탐구해보겠습니다. 라우팅의 맛을 보셨으니, 이제 데이터와 연결해볼 준비 되셨나요?


이 장은 두 라우팅 방식의 차이를 명확히 설명하고, 간단한 실습으로 실질적인 이해를 돕도록 구성했습니다. 코드도 최소화했으며, 추가 예제나 조정이 필요하면 말씀해주세요!