
exchange를 통해서 Request, Response 가져온 후에 Pre Filter를 적용시키고, 처리가 끝난 후 Post Filter를 추가하여 return을 하는 방식을 사용했다.
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom Pre Filter: Request URI -> {}", request.getId());
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("Custom Post Filter: Response code -> {}", response.getStatusCode());
}));
};
}
아래의 방식은 따로 Custom Filter를 만들지 않고 적용하는 방식이다.
spring:
cloud:
gateway:
routes:
- id: user
uri: http://localhost:8080/
predicates:
- Path=/users/**
filters:
//request와 request-header는 Key, Value의 형태다.
-AddRequestHeader=user-request, user-request-header
-AddResponseHeader=user-response, user-response-header
- id: order
uri: http://localhost:8082/
predicates:
- Path=/orders/**
filters:
//request와 request-header는 Key, Value의 형태다.
-AddRequestHeader=order-request, order-request-header
-AddResponseHeader=order-response, order-response-header
아래의 방식은 인자 값이 없는 단순한 Custom Filter을 만든 후 적용하는 방식이다.
spring:
cloud:
gateway:
routes:
- id: user
uri: http://localhost:8080/
predicates:
- Path=/users/**
filters:
- CustomFilter
- id: order
uri: http://localhost:8082/
predicates:
- Path=/orders/**
filters:
- CustomFilter
아래처럼 default-filters 속성을 사용해서 커스터마이징한 Filter와 Config의 속성들에 값을 넣어주면 되고, 추가적으로 인자 값이 필요하기 때문에 주입해줘야 한다.
Ordered.HIGHEST_PRECEDENCE 또는 Ordered.LOWEST_PRECEDENCE 키워드는 Filter의 순서를 설정해준다. Ordered.HIGHEST_PRECEDENCE은 먼저, Ordered.LOWEST_PRECEDENCE는 가장 나중에 실행이 된다고 생각하면 됨
@Component
@Slf4j
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {
public LoggingFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Logging Filter baseMessage = {}", config.getBaseMessage());
//Pre Filter
if (config.preLogger) {
log.info("Pre Filter Request ID = {}", request.getId());
}
//Post Filter
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (config.postLogger) {
log.info("Post Filter Response Code = {}", response.getStatusCode());
}
}));
},Ordered.HIGHEST_PRECEDENCE);
return filter;
}
//Config 클래스 static인 것에 주의
@Data
public static class Config {
//아래의 속성들은 application.yml에서 주입
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
spring:
application:
name: api-gateway
cloud:
gateway:
default-filters:
- name: LoggingFilter
args:
baseMessage: Logging Filter
preLogger: true
postLogger: true
routes:
- id: user
uri: http://localhost:8080/
predicates:
- Path=/users/**
eureka:
instance:
instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:8761/eureka
잘못된 정보는 지적해주시면 감사하겠습니다.