Java Code로 작성한 Filter와 Property에서 간단하게 작성한 Filter 외에 이번에는 Custom을 하여 작성했다.
server:
port: 8000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: first-service
uri: http://localhost:8081/
predicates:
- Path=/first-service/**
filters:
- CustomFilter
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
filters:
- CustomFilter
달라진 점은 filters에 CustomFilter를 넣어준다. 이름이 항상 CustomFilter인 것은 아니고 아래서 CustomFilter class를 만들어 줄 것이다.
@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public CustomFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(CustomFilter.Config config) {
// Custom pre Filter
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom PRE filter : request id -> {}", request.getId());
// Custom Post Filter
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("Custom PRE filter : response id -> {}", response.getStatusCode());
}));
};
}
public static class Config {
// put the configuration properties
}
}
CustomFilter class를 생성해주고 Component로 등록을 해 준다.
Filter를 커스텀할 때 AbstractGatewayFilterFactory<CustomFilter.Config>
를 상속 받아서 등록해야 한다. 내부 클래스 CustomFilter.Config를 만들어주고 매개변수로 받았다.
그 다음에 apply를 구현해 주면 되는데 여기에는 GatewayFilter를 반환해준다. 여기에서 JWT 등을 사용한다면 체크해 볼 수 있다.
반환 값을 보면 exchange와 chain이 있는데 람다식으로 구현을 해 주었다. 네티 비동기 서버를 사용하기 때문에ServerHttpRequest
와 ServerHttpResponse
를 사용한다. Servlet
과 비슷한 역할을 한다.
일단, 위에서 pre Filter를 정의한다. request와 response 객체를 생성해 주고 로그를 하나 찍어보았다. 이 정보를 가지고 처리하기 위해 각 서비스로 들어가게 된다. 아래에서는 Post Filter를 정의해 줄 수 있는데 먼저, filter()
안에 어떤 Filter를 적용할 것인지 지정할 수 있다. 지금은 공부하는 단계라 상태 코드를 출력하는 로그를 하나 넣어주었다. 또, Mono 데이터 타입을 줄 수 있는데 데이터 타입을 하나 주겠다는 뜻이다.