Skip to content

12. How to route based on RouterFunction

이진혁 edited this page Jun 1, 2021 · 4 revisions

웹플럭스에서는 어노테이션 기반 방식 말고 보다 더 Functional한 프로그래밍을 할 수 있도록
RouterFunction을 통한 라우팅 방식을 제공합니다.
오늘은 이 RouterFunction 라우팅 방식에 대해 알아보도록 하겠습니다.

다음은 RouterFunction 예제입니다.

@Configuration
public class RouterFunctionTestRouter {

    @Bean
    public RouterFunction<?> route(RouterFunctionTestHandler testHandler) {
        return RouterFunctions.route()
                .POST(
                        "/test",
                        RequestPredicates.accept(MediaType.APPLICATION_JSON)
                                .and(RequestPredicates.contentType(MediaType.APPLICATION_JSON)),
                        testHandler::testHandler
                ).build();
    }
}

RouterFunction은 웹플럭스에서 인터페이스로 제공하고 있으며,
쉽게 구현할 수 있도록 RouterFunctions라는 정적 팩토리 클래스도 함께 제공합니다.
따라서 직접 RouterFunction을 구현하는 것보다는RouterFunctions 클래스를 이용해서
RouterFunction을 작성하는 것이 일반적입니다.

RouterFunction은 기존 어노테이션 기반 라우팅에서는 찾아볼 수 없었던 개념이긴 한데,
컨트롤러를 한 대 모아놓은 것이라고 생각하면 쉽습니다.
여러 컨트롤러(라우터)들의 엔트리포인트를 RouterFunction에 모아두고
이후에 나올 RouterHandler에게 실제 라우팅을 넘기는 것입니다.

위 예제에서는 HTTP MethodPOST를 사용하였고,
경로는 /test이며 오고 가는 Request Bodyapplication/json으로 구성하며
실제 /test로 오는 요청은 RouterFunctionTestHandler 컴포넌트의
testhandler() 메소드로 처리하겠다는 것을 알 수 있습니다.

현재는 하나의 엔트리포인트밖에 없지만 여러 개 있을 경우
andRouter() 메소드로 라우터를 추가할 수 있습니다.

다음은 HandlerFunction의 예제입니다.

@Component
@RequiredArgsConstructor
public class RouterFunctionTestHandler {

    private final RouterFunctionTestService testService;

    public Mono<ServerResponse> testHandler(ServerRequest request) {
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(request.bodyToMono(RouterFunctionTestRequest.class).flatMap(req -> Mono.just(
                        new RouterFunctionTestResponse(
                                testService.combineName(req.getFirstName(), req.getLastName()),
                                req.getAge(),
                                testService.combineGradeClassNumber(req.getGrade(), req.getClassroom(), req.getNumber())
                        )
                )), RouterFunctionTestResponse.class);
    }
}

HandlerFunction에서는 기존 컨트롤러가 행하던 일들을 처리합니다.
기존에 사용하던 @RequestBody와 같은 어노테이션 대신
모든 RequestServerRequest 객체를 사용하며
리턴하는 값도 ServerResponse를 통해 하게 됩니다.
여기서 사용되는 서비스 객체는 기존과 다를 바가 없습니다.

이렇게 RouterFunction -> HandlerFunction
-> Service -> Repository 순으로 처리를 하는 방법이
RouterFunction 처리 방식입니다.

Example

RouterFunction 기반으로 라우팅하기