https://sundaland.tistory.com/360
[ ▶ Functional Endpoints (Serving Resources,Running a Server,Filtering Handler Functions) ]
Spring Web MVC의 WebMvc.fn에서 제공하는 RouterFunction은 웹 애플리케이션에서 요청을 처리하기 위한 함수형 프로그래밍 모델이다. 이 모델은 함수형 스타일을 사용하여 HTTP 요청을 처리하는 방식을 제공하며, 여러 유연한 기능들을 포함한다.
[ ▷ 리소스 제공 (Serving Resources) ]
RouterFunction을 사용하면 정적 리소스를 제공하거나 특정 조건에 맞는 요청을 리소스로 리디렉션할 수 있다. 예를 들어, SPA(Single Page Application)에서 리디렉션을 통해 단일 진입점(index.html)으로 모든 요청을 처리하는 경우 유용하다.
△ 리소스로 리디렉션
특정 요청을 처리할 때, 조건에 따라 리소스로 리디렉션할 수 있다. SPA에서 모든 비-API 요청을 index.html로 리디렉션하는 방식이 대표적이다.
ClassPathResource index = new ClassPathResource("static/index.html");
List<String> extensions = Arrays.asList("js", "css", "ico", "png", "jpg", "gif");
// /api/** 경로나 확장자가 js, css, ico 등이 아닌 경우에만 index.html로 리디렉션
RequestPredicate spaPredicate = path("/api/**")
.or(path("/error"))
.or(pathExtension(extensions::contains)).negate();
RouterFunction<ServerResponse> redirectToIndex = RouterFunctions.route()
.resource(spaPredicate, index)
.build();
- RequestPredicate: /api/**, /error 경로 이외의 요청이거나 지정된 확장자가 포함되지 않는 요청을 처리하는 조건을 정의한다.
- resource(): 리소스를 반환하는 함수이다. 여기서는 요청을 index.html로 리디렉션한다.
△ 루트 경로에서 리소스 제공
루트 경로 또는 지정된 경로에서 정적 리소스를 제공할 수 있다. 예를 들어, /resources/**로 시작하는 모든 요청에 대해 public-resources/ 디렉토리의 리소스를 제공할 수 있다.
Resource location = new FileSystemResource("public-resources/");
RouterFunction<ServerResponse> resources = RouterFunctions.resources("/resources/**", location);
- resources(): 특정 경로 패턴과 루트 위치를 기반으로 리소스를 제공하는 라우터를 생성한다.
[ ▷ 서버 실행 및 라우팅 설정 ]
WebMvc.fn에서 작성된 RouterFunction은 일반적으로 Spring의 DispatcherHandler 또는 DispatcherServlet과 함께 동작한다. 이를 위해 MVC 설정에서 필요한 구성 요소들을 정의하고, 라우터 함수를 Bean으로 등록하여 Spring이 이를 감지하고 사용할 수 있도록 한다.
△ Spring 설정 클래스
@Configuration
@EnableMvc
public class WebConfig implements WebMvcConfigurer {
@Bean
public RouterFunction<?> routerFunctionA() {
// 라우터 함수 정의
}
@Bean
public RouterFunction<?> routerFunctionB() {
// 라우터 함수 정의
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// 메시지 변환기 설정
}
@Override
public void addCorsMappings(CorsRegistry registry) {
// CORS 설정
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// 뷰 리졸버 설정
}
}
- RouterFunctionMapping: Spring에서 여러 RounterFunction<?> Bean을 감지하고 결합한다. 여러 라우터 함수를 겨합해 요청을 처리하는데 사용된다.
- HandlerFunctionAdapter: DispatcherHandler가 HandlerFunction을 호출할 수 있도록 어댑터 역할을 한다.
- WebMvcCOntfigurer: 메시지 변환기, CROS 설정, 뷰 리졸버 등의 전역 설정을 할 수 있는 인터페이스이다.
[ ▷ 필터링 (Filtering Handler Functions) ]
WebMvc.fn에서는 before, after, filter와 같은 메서드를 통해 특정 라우트에 필터를 적용할 수 있다. 이는 요청 전후에 특정 작업을 수행하거나, 보안 검사를 추가하는 등의 목적으로 사용된다.
△ Before & After 필터
- before: 요청을 처리하기 전에 실행되는 필터이다.
- after: 요청을 처리한 후에 실행되는 필터다.
RouterFunction<ServerResponse> route = RouterFunctions.route()
.path("/person", b1 -> b1
.nest(accept(MediaType.APPLICATION_JSON), b2 -> b2
.GET("/{id}", handler::getPerson)
.GET(handler::listPeople)
.before(request -> ServerRequest.from(request)
.header("X-RequestHeader", "Value")
.build())) // 요청 전에 특정 헤더 추가
.POST(handler::createPerson))
.after((request, response) -> logResponse(response)) // 응답 후 로깅
.build();
- before(): 두 GET 요청에 대해 요청 전에 특정 헤더를 추가하는 필터이다.
- after(): 모든 요청이 처리된 후, 응답을 로깅하는 필터이다.
△ Filter 메서드
filter() 메서드는 요청 처리 전후에 특정 로직을 추가할 수 있는 강력한 기능이다. 보안 검증이나 로깅을 처리할 수 있다.
SecurityManager securityManager = ...;
RouterFunction<ServerResponse> route = RouterFunctions.route()
.path("/person", b1 -> b1
.nest(accept(MediaType.APPLICATION_JSON), b2 -> b2
.GET("/{id}", handler::getPerson)
.GET(handler::listPeople))
.POST(handler::createPerson))
.filter((request, next) -> {
// 요청 경로에 대해 보안 검사를 수행
if (securityManager.allowAccessTo(request.path())) {
return next.handle(request); // 요청 처리 계속 진행
} else {
return ServerResponse.status(HttpStatus.UNAUTHORIZED).build(); // 인증 실패
}
})
.build();
- filter(): 요청이 들어올 때 보안 검사를 수행하고, 접근이 허용된 경우에만 다음 핸들러 함수를 호출한다. 그렇지 않으면 401 Unauthorized 응답을 반환환다.
[ ▷ CORS 지원 (Cross-Origin Resource Sharing) ]
WebMvc.fn에서도 CORS 지원을 제공하는 CorsFilter를 통해 Cross-Origin 요청을 처리할 수 있다. WebMvcConfigurer를 사용해 전역적으로 CORS 설정을 추가하거나, 특정 라우터 함수에 대해 CORS 규칙을 적용할 수 있다.
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://example.com")
.allowedMethods("GET", "POST");
}
/ 경로에 대한 모든 요청에 대해 특정 도메인에서 오는 요청을 허용하며, GET 및 POST 메서드를 사용할 수 있도록 설정한다.
[ ▷ 필터의 순서 및 적용 범위 ]
필터는 특정 경로에만 적용되거나, 특정 요청 전/후에만 동작하도록 세밀하게 설정할 수 있다. 예를 들어, 중첩된 경로에서만 적용되는 필터를 설정하거나, 특정 라우트에만 필터를 적용할 수 있다.
- 필터는 순차적으로 실행되며, 여러 필터가 적용된 경우 차례대로 실행된다.
- before, after와 같은 필터는 중첩된 라우트 내에서만 동작할 수 있다.
[ ▷ 요약 ]
- RouterFunction을 통해 Spring Web MVC에서 요청을 처리하는 방식이 더욱 유연해진다. 라우팅, 리소스 제공, 필터링 등의 작업을 함수형 스타일로 간결하게 표현할 수 있다.
- Servin Resources 기능은 정적 파일 제공이나 리디렉션에 유용하며, SPA 애플리케이션에서 특히 많이 사용된다.
- 필터를 통해 요청 전후에 보안 검증, 로깅 등의 작업을 추가할 수 있다.
- Spring 설정을 통해 RouterFunction을 Spring Bean으로 등록하여 DispatcherServlet과 함께 사용할 수 있다.
'Web on Servlet Stack' 카테고리의 다른 글
MVC Config API (0) | 2024.10.15 |
---|---|
Enable MVC Configuration (0) | 2024.10.15 |
DispatcherServlet (0) | 2024.10.14 |
RounterFunction (0) | 2024.10.14 |
Functional Endpoints Overview (0) | 2024.10.14 |