아래는 **"스프링부트 웹플럭스 시리즈"**의 **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<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` 같은 어노테이션을 사용해 직관적으로 엔드포인트를 정의하죠. 비교를 위해 이전 예제를 다시 보겠습니다:

```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<String> sayHello() {
        return Mono.just("Hello, WebFlux!");
    }
}
```

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

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

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

### 요청 처리와 응답 생성 실습

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

```java
@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!"가 출력됩니다. 이렇게 함수형 라우팅은 요청 데이터를 쉽게 처리하고, `Mono`나 `Flux`로 응답을 확장할 수도 있습니다.

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

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

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

### 어떤 걸 선택해야 할까?

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

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

### 마무리

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

---

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