Inflean MSA 강의 도중에 AbstractGatewayFilterFactory가 궁금해서 블로그를 찾아보다가 잘 정리된 글이 있어서 참고해서 정리해서 올려둔다....(
사실따라쓰기 수준임..)
인프런 MSA 강의에서는 spring cloud Gateway가 제공하는 2가지 방법을 했었다.
이번엔 우리가 원하는 기능을 수행하는 Custom Filter를 만들고자 한다.
사전에 실행하는 pre 부분과
사후에 실행하는 post 부분으로 나눌 수 있으며 Config 클래스의 필드를 값을 정의하여
원하는 데이터들을 매개변수로 받을 수 있다.
routes:
- id: first-service
uri: http://127.0.0.1:8001/
predicates:
- Path=/first-service/**
filters:
- CustomFilter
# - AddRequestHeader=first-request, first-request-header2
# - AddResponseHeader=first-response, first-response-header2
- id: second-service
uri: http://127.0.0.1:8002/
predicates:
- Path=/second-service/**
filters:
- CustomFilter
# - AddRequestHeader=second-request, first-second-header2
# - AddResponseHeader=second-response, first-second-header2
위와 같이 yml설정 파일에서 원하는 서비스 filters에 클래스 이름을 등록하여 사용한다.
Global Filter로 등록하는 경우에는
위와 같이 spring.cloud.gateway.default-filters에 클래스 이름과
Config에 설정한 필드들의 이름을 파라미터로 받아서 값을 보낼 수 있다.
아래 코드는 AbstractGatewayFilterFactory의 apply메소드를 구현한 부분이다.
@Override
public GatewayFilter apply(Config config) {
//Custom Pre Filter
return (exchange,chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom Pre filter -> {}", request.getId());
//Custom POST Filter
return chain.filter(exchange).then(Mono.fromRunnable(() ->{
log.info("Custom POST filter : response code -> {}" , response.getStatusCode());
}));
//Mono는 전달하려는 객체가 단일값인 경우 사용한다.
};
}
return 내용을 보게 되면 exchange와 chain을 파라미터로 받고, GatewayFilter를 반환하는
람다식을 구현했다.
여기서 그럼 GatewayFilter는 무엇일까?
위 람다식을 풀어서 쓰면
GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Logging Pre filter baseMessage -> {}", config.getBaseMessage());
if (config.isPreLogger())
log.info("Logging Pre filter Start : requestId-> {}", request.getId());
//Custom POST Filter
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (config.isPostLogger())
log.info("Logging POST filter End : response code -> {}", response.getStatusCode());
}));
}, Ordered.HIGHEST_PRECEDENCE);
return filter;
}
위와 같은 람다식으로 표현이 가능하다.
WebFlux에서는 ServletRequest 나 ServletResponse를 더이상 사용하지 않는다.
exchange 파라미터는 ServletRequest Response를 WebFlux에서 사용하는
ServerRequest를 변경해준다.
chain은 postFilter를 적용하기 위한 파라미터이다.