스프링 리액터 시작하기 (8) - webflux.fn filter handler , webflux config

brian Byeon·2022년 5월 3일
0

0. 자료의 출처

https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-fn-running

오해가 없도록 어떤 text를 인용했는지 원문을 첨부합니다.🤗

1. Filter Handler Functions

handler함수는 사용자의 요청을 처리해주는 함수이다. 이런 Handler함수들을 routing function builder에서 before,after, filter 메서드를 이용해서 필터시킬 수 있다. Annotation기반 프로그래밍에서 @ControllerAdvice, ServletFilter 등으로 했던 것을 동일하게 할 수 있다. 이 필터들은 자신에게 오는 모든 request들을 필터하기 때문에, nested routes안에서 필터를 걸면 그 바깥의 route들은 영향을 받지 않는다.

RouterFunction<ServerResponse> route = route()
    .path("/person", b1 -> b1
        .nest(accept(APPLICATION_JSON), b2 -> b2
            .GET("/{id}", handler::getPerson)
            .GET(handler::listPeople)
            .before(request -> ServerRequest.from(request) 
                .header("X-RequestHeader", "Value")
                .build()))
        .POST("/person", handler::createPerson))
    .after((request, response) -> logResponse(response)) 
    .build();

중간에 before이 나오는데, /person경로에 대한 nested route이다. 이 before은 이 nested안에 있는 route들에만 적용되기 때문에

            .GET("/{id}", handler::getPerson)
           .GET(handler::listPeople)

이 두개에만 적용이 된다. 헤더를 더해주는 역할을 하고 있다. 아래 있는 after는 눈치를 챘겠지만

    .after((request, response) -> logResponse(response)) 

모든 route (nested안에 있는 GET 들도)에 대해서 log를 남기는 필터이다.

filter메서드는 HandlerFilterFunction을 인자로 받는다. HandlerFilterFunction은 ServerRequest와 HandlerFunction을 인자로 받아서 ServerResponse를 return해준다. 만약 여러개의 필터가 있다면 HandlerFunction은 다음 필터를 가리키고, 아니라면 route되는 handler를 가리키게 된다. 이를테면 보안 필터같은 것을 걸어놓을 수 있다. 아래는 특정 path가 allow되는지 체크하는 필터이다.

SecurityManager securityManager = ...

RouterFunction<ServerResponse> route = route()
    .path("/person", b1 -> b1
        .nest(accept(APPLICATION_JSON), b2 -> b2
            .GET("/{id}", handler::getPerson)
            .GET(handler::listPeople))
        .POST("/person", handler::createPerson))
    .filter((request, next) -> {
        if (securityManager.allowAccessTo(request.path())) {
            return next.handle(request);
        }
        else {
            return ServerResponse.status(UNAUTHORIZED).build();
        }
    })
    .build();

next.handle()을 부르는 것이 optional하다. 즉 필터의 조건에 맞지 않으면 다음 필터나 handler로 안 넘어가게 한다. builder를 사용하지 않아도 router function이 존재하면 RouterFunction.filter(HandlerFilterFunction)을 해서 필터를 적용할 수 있다.

2. WebFlux config

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
}

일단 EnableWebFlux를 사용해서 Spring WebFlux infrastructure beans를 사용할 수 있다.
또, WebFluxConfigurer interface를 사용해서 여러가지 설정을 추가할 수 있다.

가장 익숙한 설정은 ViewResolver가 있을 것이다

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        // ...
    }
}

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.freeMarker();
    }

    // Configure Freemarker...

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPath("classpath:/templates");
        return configurer;
    }
}

아래와 같이 ViewResolverRegistry는 여러 view에 대한 shortcut을 가지고 있어서 손쉽게 설정을 만들 수 있다.

0개의 댓글