아래는 **"스프링부트 웹플럭스 시리즈"**의 **5장: 웹플럭스에서 라우팅 처리"**에 대한 초안입니다. 4장의 흐름을 이어가며 웹플럭스의 두 가지 라우팅 방식(함수형 라우팅과 어노테이션 기반 컨트롤러)을 비교하고, 실습 예제를 간략히 포함했습니다. 초보자가 이해하기 쉽도록 단계별로 설명하며 자연스러운 문체를 유지했습니다. --- ## 5. 웹플럭스에서 라우팅 처리 지난 장에서 `Mono`와 `Flux`로 리액티브 스트림의 기본을 익혔습니다. 이제 이 스트림을 클라이언트 요청에 연결하는 방법을 배워볼 차례입니다. 웹플럭스에서는 라우팅을 처리하는 두 가지 주요 방식이 있습니다: **함수형 라우팅(RouterFunction)**과 **어노테이션 기반 컨트롤러**. 이번 장에서는 두 접근법을 살펴보고, 각각의 장단점을 비교하며 간단한 예제를 작성해보겠습니다. 자, 시작합시다! ### RouterFunction을 사용한 함수형 라우팅 웹플럭스는 함수형 프로그래밍 스타일을 지원하며, `RouterFunction`을 통해 라우팅을 정의할 수 있습니다. 이 방식은 선언적으로 경로와 핸들러를 연결하며, 코드가 간결하고 유연하다는 장점이 있습니다. 전통적인 컨트롤러보다 더 리액티브 철학에 가까운 접근법이죠. 먼저, 3장에서 만든 프로젝트에 새로운 클래스를 추가합니다. `src/main/java/com/example/demo` 경로에 `RouteConfig` 클래스를 만들고 아래 코드를 작성해보세요: ```java 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 routes() { return route(GET("/functional/hello"), request -> ServerResponse.ok().bodyValue("Hello from RouterFunction!")); } } ``` - `@Configuration`: 스프링 설정 클래스임을 나타냅니다. - `RouterFunction`: 요청 경로와 응답을 정의합니다. - `route()`: `/functional/hello`로 들어오는 GET 요청에 대해 "Hello from RouterFunction!"를 반환합니다. 애플리케이션을 실행하고 `http://localhost:8080/functional/hello`로 접속해보세요. 간단한 문자열 응답이 표시될 겁니다. 이 방식은 컨트롤러 클래스 없이도 라우팅을 처리할 수 있어, 코드 구조를 간소화할 수 있습니다. ### 어노테이션 기반 컨트롤러와의 비교 4장에서 사용했던 어노테이션 기반 컨트롤러는 스프링 MVC와 비슷한 방식으로 동작합니다. `@RestController`, `@GetMapping` 같은 어노테이션을 사용해 직관적으로 엔드포인트를 정의하죠. 비교를 위해 이전 예제를 다시 보겠습니다: ```java 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 sayHello() { return Mono.just("Hello, WebFlux!"); } } ``` 이제 두 방식의 차이를 표로 정리해보겠습니다: | **특징** | **어노테이션 기반 컨트롤러** | **RouterFunction (함수형)** | |---------------------|----------------------------------|----------------------------------| | **문법** | `@GetMapping`, `@PostMapping` 등 | `route()`, `GET()`, `POST()` 등 | | **구조** | 클래스와 메서드 중심 | 함수와 람다 중심 | | **익숙함** | MVC 경험자라면 쉽게 적응 | 함수형 프로그래밍에 익숙해야 함 | | **유연성** | 정해진 구조로 간단히 작성 | 동적 라우팅이나 조건부 처리에 강점 | | **용도** | 전통적인 REST API에 적합 | 리액티브 철학을 살린 경량 애플리케이션 | 어노테이션 방식은 익숙하고 직관적이어서 초보자에게 추천할 만합니다. 반면, 함수형 라우팅은 더 가볍고 유연하며, 대규모 프로젝트에서 라우팅 로직을 한 곳에 모아 관리하기 좋습니다. ### 요청 처리와 응답 생성 실습 함수형 라우팅으로 조금 더 실습해보죠. 이번엔 요청 파라미터를 받아 응답을 만들어봅시다. `RouteConfig`에 새 경로를 추가합니다: ```java @Bean public RouterFunction 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!"가 출력됩니다. 이렇게 함수형 라우팅은 요청 데이터를 쉽게 처리하고, `Mono`나 `Flux`로 응답을 확장할 수도 있습니다. 어노테이션 방식으로 동일한 기능을 구현한다면: ```java @GetMapping("/greet/{name}") public Mono greet(@PathVariable String name) { return Mono.just("Hello, " + name + "!"); } ``` 두 방식 모두 결과는 같지만, 코드 스타일과 구조에서 차이가 느껴지죠? ### 어떤 걸 선택해야 할까? - **어노테이션 기반**: 팀이 MVC에 익숙하거나, 빠르게 REST API를 만들고 싶을 때. - **함수형 라우팅**: 리액티브의 장점을 극대화하거나, 경량화된 라우팅 로직이 필요할 때. 프로젝트 성격과 팀의 선호도에 따라 선택하면 됩니다. 처음엔 어노테이션 방식으로 시작해, 익숙해지면 함수형으로 넘어가보는 것도 좋은 전략입니다. ### 마무리 이번 장에서 웹플럭스의 라우팅 방식을 두 가지 맛으로 경험해봤습니다. 어노테이션 기반은 친숙하고, 함수형은 새롭고 강력하죠. 다음 장에서는 리액티브 데이터베이스와의 연동을 다루며, 웹플럭스의 실무적인 면모를 더 깊이 탐구해보겠습니다. 라우팅의 맛을 보셨으니, 이제 데이터와 연결해볼 준비 되셨나요? --- 이 장은 두 라우팅 방식의 차이를 명확히 설명하고, 간단한 실습으로 실질적인 이해를 돕도록 구성했습니다. 코드도 최소화했으며, 추가 예제나 조정이 필요하면 말씀해주세요!