Gateway Filter
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4/dashboard
강의를 보고 학습했으며 3장 Gateway를 학습하고 느낀점을 정리해봤다.
1 . Spring Cloud Gateway 필터에서의 exchange와 chain
Spring Cloud Gateway에서 필터를 작성할 때, 람다식으로 exchange와 chain이라는 매개변수를 사용하는 코드를 자주 접하게 되었다. 이 두 객체가 무엇을 의미하며, 어떻게 주입되는지, 그리고 각각의 역할이 무엇인지 궁금했다.
exchange란?
exchange는 Spring WebFlux에서 제공하는 ServerWebExchange 객체로, 클라이언트 요청(Request)과 서버 응답(Response)을 모두 포함하는 컨테이너이다. 이 객체는 HTTP 요청과 응답에 대한 모든 데이터를 관리한다.
- 주요 구성 요소:
ServerHttpRequest: HTTP 요청 정보를 담고 있다 (예: 요청 URL, 헤더, 쿼리 파라미터 등)ServerHttpResponse: HTTP 응답 정보를 담고 있다 (예: 응답 상태 코드, 헤더, 바디 등)
chain이란?
chain은 Spring Cloud Gateway에서 제공하는 GatewayFilterChain 객체로, 현재 필터에서 다음 필터로 요청을 전달하는 역할을 한다. 이를 호출하지 않으면 체인이 중단되며, 요청이 다음 단계로 전달되지 않는다.
- 주요 역할:
- 필터 체인의 흐름을 제어하며, 요청을 처리할 다음 필터로 넘기거나 종료
어떻게 주입되는가?
exchange와 chain은 Spring Cloud Gateway가 요청을 처리할 때 자동으로 생성되며, 각 필터의 filter 메서드가 호출될 때 주입된다. 개발자는 이 객체를 직접 생성하지 않아도 되고, 단순히 전달된 객체를 사용하면 된다.
2. Gateway 필터 체인과 AOP의 유사성
필터 체인은 AOP(Aspect-Oriented Programming)와 비슷한 방식으로 동작하는지 궁금했다. 학습을 통해, 둘 다 요청 전후에 부가 작업을 추가할 수 있는 구조라는 점에서 유사성을 가지지만, 구현 방식에 차이가 있다는 것을 알게 되었다.
AOP에서의 joinPoint.proceed()
- AOP에서 메서드 실행 전후에 부가 작업을 수행할 때
joinPoint.proceed()를 호출한다. proceed()를 호출하지 않으면 메서드 실행이 중단되며, 이후의 작업도 실행되지 않는다.
Gateway 필터 체인에서의 chain.filter(exchange)
- 필터 체인에서
chain.filter(exchange)를 호출하면 요청이 다음 필터로 전달된다. - 이를 호출하지 않으면 체인이 중단되며, 요청이 더 이상 처리되지 않는다.
- 비동기 방식으로 동작하며, 체인의 끝에 도달하면 최종적으로 실제 API 서버로 요청이 전달된다.
결론적으로, 필터 체인과 AOP는 요청 전/후 작업을 처리한다는 점에서 비슷하지만, 필터 체인은 비동기 이벤트 흐름을 기반으로 작동한다는 차이가 있다.
3. Config 객체의 필요성과 역할
Spring Cloud Gateway에서 AbstractGatewayFilterFactory를 상속받아 필터를 구현할 때, Config라는 객체가 필요하다. 처음에는 비어 있는 경우도 많아서 "이 객체가 꼭 필요한가?"라는 의문이 들었다. 하지만 Config 객체는 필터 동작을 커스터마이징하기 위한 설정값을 담는 역할을 한다는 점을 알게 되었다.
왜 필요한가?
- Gateway 필터는 각 필터마다 설정값을 다르게 지정할 수 있도록 설계되었다.
Config객체는 이런 설정값을 담아, 특정 필터의 동작을 유연하게 변경할 수 있도록 도와준다.
비어 있는 Config 객체의 이유
- 초기에는 별도의 설정값이 필요하지 않을 수 있다. 하지만, 확장 가능성을 염두에 두고
Config객체가 설계되었다. - 예를 들어, 특정 조건에 따라 로깅 여부를 설정하거나, 헤더 값을 동적으로 추가하는 등 다양한 동작을 커스터마이징할 수 있다.
실제 활용 사례
다음은 Config 객체를 활용한 예제이다
@Getter
@AllArgsConstructor
public static class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
if (config.isPreLogger()) {
log.info("Pre Filter: {}", config.getBaseMessage());
}
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (config.isPostLogger()) {
log.info("Post Filter: {}", config.getBaseMessage());
}
}));
};
}
baseMessage와preLogger,postLogger값을 사용해 필터 동작을 제어한다.- YAML 설정을 통해 각 필터의 동작을 동적으로 변경 가능
spring:
cloud:
gateway:
routes:
- id: logging-filter
uri: http://example.com
filters:
- name: LoggingFilter
args:
baseMessage: "Logging Filter Active"
preLogger: true
postLogger: true
4. OrderedGatewayFilter와 GatewayFilter의 차이
Spring Cloud Gateway에서 필터를 구현할 때, GatewayFilter와 OrderedGatewayFilter라는 두 가지 선택지가 있다. 처음 이를 접했을 때 "이 둘의 차이가 무엇인지" 궁금했다. 학습을 통해 아래와 같은 차이를 알게 되었다.
GatewayFilter
- 기본 필터 인터페이스로, 필터의 핵심 로직을 구현
- 요청/응답을 처리하는 가장 기본적인 단위
- 실행 순서를 명시적으로 제어할 수는 없다
OrderedGatewayFilter
GatewayFilter를 확장한 구현체로, 필터의 실행 순서를 명시적으로 지정할 수 있다.- 생성 시 실행 우선순위를 설정
GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Logging Filter baseMessage: {}", config.getBaseMessage());
if (config.isPreLogger()) {
log.info("Logging PRE Filter Start: request id -> {}", request.getId());
}
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (config.isPostLogger()) {
log.info("Logging POST Filter End: response Status code -> {}", response.getStatusCode());
}
}));
}, Ordered.LOWEST_PRECEDENCE);
return filter;
- 두 번째 매개변수로 우선순위를 지정하며, 값이 작을수록 높은 우선순위를 가짐
결론
- 단순한 필터 로직을 구현할 때는
GatewayFilter를 사용 - 필터 실행 순서를 명시적으로 제어해야 한다면
OrderedGatewayFilter를 사용
'Spring > Spring Cloud' 카테고리의 다른 글
| Spring Cloud3. Netty (1) | 2024.12.13 |
|---|