실무 프로젝트로 배우는 Kotlin & Spring/스프링 WebFlux 이해하기

함수형 엔드포인트

webmaster 2022. 12. 2. 19:16
728x90

함수형 엔드포인트

스프링 WebFlux는 클라이언트의 요청을 라우팅하고 처리할 수 있는 람다 기반 프로그래밍 모델인 함수형 엔드포인트를 제공한다.

함수형 엔드포인트는 요청을 분석해 핸들러로 라우팅 하는 라우터 함수 과 요 청 객체를 전달받아 응답을 제공하는 핸들러 함수로 이뤄져 있다.

라우터 함수

@Configuration
class Router { // 클라이언트로부터 전달받을 요청을 해석하고, 핸들러로 전달
    //Configuration 과 Bean 에노테이션을 통해 빈으로 등록해야한다.
    @Bean
    fun userRouter(handler: UserHandler): RouterFunction<ServerResponse> =
        /*
        route()
            .GET("/users/{id}", handler::getUser) //중복되는 경로는 중첩라우터를 사용해서 매핑할 수 있다.
            .GET("/users", handler::getAll)
        .build()
         */
        router {
            "/users".nest {
                GET("/{id}", handler::getUser)
                GET("/", handler::getAll)
            }
        }
}
  • 라우터 함수는 클라이언트로부터 전달받은 요청을 해석하고 그에 맞는 핸들러로 전달하는 역할을 한다.
  • 라우터 함수는 @Configuration에 RouterFunction을 반환하는 Bean으로 등록할 수 있으며, 빈의 이름을 다르게 하여 여러 개의 라우터 함수를 등록할 수 있다.
  • 라우터 함수는 URI 패턴 매칭에 따른 분배 역할을 위해 RouterFuctions.route() 라는 유용한 빌더를 제공하고 있다.
    • RouterFuctions.route()를 사용하면 HTTP 요청 메서드 GET/POST/PUT/DELETE 등에 대한 매핑을 위한 편리한 함수를 제공하고, 목적에 맞게 URI 패턴을 등록하여 라우팅 룰을 생성할 수 있다.
  • 중복된 경로를 그룹화 하고 싶은 경우 중첩 라우터를 사용하면 되며, 중첩 라우터를 사용해 그룹화하면 코드 중복이 제거되고, 가독성이 좋은 라우터 함수를 작성할 수 있다(nest)

핸들러 함수

@Component
class UserHandler {

    val users = listOf(
        User(id = 1, email = "user1@gmail.com"),
        User(id = 2, email = "user2@gmail.com")
    )

    fun getUser(req: ServerRequest): Mono<ServerResponse> =
        users.find {
            req.pathVariable("id").toLong() == it.id //해당 부분을 어노테이션이 아닌 함수형 스럽게 받아올 수 있다
        }?.let {
            ServerResponse.ok().bodyValue(it)
        } ?: ServerResponse.notFound().build()

    fun getAll(req: ServerRequest): Mono<ServerResponse> = ServerResponse.ok().bodyValue(users)
}
  • 라우터 함수로부터 전달받은 요청 객체인 ServerRequest를 이용해 로직을 처리한 후 응답 객체인 ServerResponse를 생성한 뒤 반환한다.
  • ServerRequest, ServerResponse는 불변 객체로 설계되었다.
  • 기본적으로 리액터의 Publisher인 Mono, Flux로 응답 본문을 작성한다.
728x90