[Spring Cloud Gateway] Filter 적용
Spring Cloud Gateway에서 필터가 어떤한 동작에 의해 작동하는지, 프로세스를 살펴보자.
Filter의 프로세스
클라이언트가 First Service 혹은 Second Service를 사용하고 싶다고 할 때, Spring Cloud gateway가 중간에 자리잡고 있다.
클라이언트가 게이트웨이에 어떠한 요청을 전달하면, 게이트웨이에서 First Service로 갈 지 Second Service로 갈 지 판단 후에 서비스에 요청을 분기한다.
이 때, Spring Cloud gateway에서 일어나는 작업에 대해 더 자세히 알아보자.
첫 번째로, Gateway Handler Mapping
에서 클라이언트에게 어떤 요청 정보가 들어왔는지, 요청 정보를 받는다.
그리고 그 요청이 어떠한 이름으로 들어왔는지, Predicate
를 통해 요청을 분기해준다.
그리고 어떤 작업이 일어나기 전에, 사전 필터(Pre Filter
)가 적용되고,
어떤 작업이 일어난 뒤에 사후 필터(Post Filter
)가 적용된다.
라우팅 + Filter 적용
1. java 코드를 이용한 방식
라우팅 설정을 하면서 filter를 적용할 수 있다.
이 전에는 아래처럼 application.yml
설정을 통해 라우팅 설정을 했다면, 이번에는 java 코드를 통해 직접 라우팅 설정을 해보자.
추가로, 필터까지 설정해 볼 것이다.
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: first-service
uri: http://localhost:8081/
predicates:
- Path=/first-service/**
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
1) apigateway-service
config/FilterConfig.java
@Configuration
public class FilterConfig {
@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/first-service/**")
.filters(f -> f.addRequestHeader("first-req", "first-req-header")
.addResponseHeader("first-res", "first-res-header"))
.uri("http://localhost:8081")
)
.route(r -> r.path("/second-service/**")
.filters(f -> f.addRequestHeader("second-req", "second-req-header")
.addResponseHeader("second-res", "second-res-header"))
.uri("http://localhost:8082")
)
.build();
}
}
이는 위에 보이는 application.yml
과 같은 역할을 하며, 작성하는 방식만 다른 것이다.
2) first-service
FirstServiceController.java
@RestController
@RequestMapping("/first-service")
@Slf4j
public class FirstServiceController {
@GetMapping("/message")
public String message(@RequestHeader("first-req") String header) {
log.info("header={}", header);
return "Hello First Service";
}
}
first-req
에 들어있는 값을 로그로 남겨보자.
3) second-service
SecondServiceController.java
@RestController
@RequestMapping("/second-service")
@Slf4j
public class SecondServiceController {
@GetMapping("/message")
public String message(@RequestHeader("second-req") String header) {
log.info("header={}", header);
return "Hello Second Service";
}
}
마찬가지로 second-req
에 들어있는 값을 로그로 남겨보자.
결과 확인
http://localhost:8000/first-service/message
과 http://localhost:8000/second-service/message
에 접속해보자.
request header 확인
request는 인텔리제이의 콘솔 로그로 확인할 수 있다.
response header 확인
response는 cmd
+ option
+ i
단축키를 이용해 개발자 도구를 켜서 확인한다.
이렇게 게이트웨이에서 클라이언트의 요청을 중간에 가로채서, 추가적인 request 값이라던가 response 값을 넣고 전달할 수 있다.
또한, application.yml
파일 뿐만 아니라 java 코드로 직접 라우팅 할 수 있다.
2. application.yml
를 이용한 방식
이번에는 application.yml
을 통해 필터를 적용하는 법을 익히기 위해,
이전에 사용했던 FilterConfig
클래스의 내용을 모두 주석처리하고 진행하자.
1) apigateway-service
application.yml
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: first-service
uri: http://localhost:8081/ # 2. 이동 될 주소
predicates:
- Path=/first-service/** # 1. 사용자가 입력한 조건 값
filters: # 필터 추가
- AddRequestHeader=first-req, first-req-header2 # AddRequestHeader=key, value 형태
- AddResponseHeader=first-res, first-res-header2 # AddResponseHeader=key, value 형태
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
filters: # 필터 추가
- AddRequestHeader=second-req, second-req-header2
- AddResponseHeader=second-res, second-res-header2
결과 확인
request header는 이전과 마찬가지로 인텔리제이의 콘솔 로그로 확인할 수 있다.
response header 확인
이번에는 포스트맨을 이용해 테스트해보자.
포스트맨에서 http://localhost:8000/first-service/message
과 http://localhost:8000/second-service/message
에 접속해보자.
마찬가지로 필터를 통해 헤더에 값이 잘 들어간 것을 확인할 수 있다.
💛 개인 공부 기록용 블로그입니다. 👻