Client가 요청을 하면 Spring Cloud Gateway가 어떤 Service로 갈지 결정한 다음 각 요청을 분기를 해주게 된다.
이때 Spring Cloud Gateway 안에서 일어나는 작업이 있는데 일단 Client로부터 어떤 요청이 들어왔는지 Gateway Handler Mapping이 요청 정보를 받고 그 요청에 대한 조건 즉, 어떤 분기를 요청했는지 구분하는 것을 Predicate가 맡아 한다.
그다음에 Pre Filter(사전 필터), Post Filter(사후 필터)로 요청 정보를 구성할 수 있다. Pre FIlter를 거쳐 요청 정보가 들어와 요청 정보에 대한 처리를 마치고 Post Filter를 통해 다시 Gateway Handler Mapping으로 Client에게 전달이 된다고 보면 된다.
위에서 Filter에 대해 설명했는데 사전 필터와 사후 필터에 대한 과정을 Property에서 해줄 수도 있고 Java Code로도 해줄 수 있다.
Property에서 하면 appilcation.yml에서 관리를 할 수 있다. Java Code로 한다면 Config를 하나 생성해 주고 관리를 할 수 있다. 이번에는 Java Code로 Filter를 사용하는 것에 대해 진행하려고 한다.
server:
port: 8000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: apigateway-service
yml에서는 Java Code로 Filter를 구현할 것이기 때문에 geteway.routes를 따로 설정해 주지 않는다. 지금은 지워뒀는데 주석을 처리하거나 설정해서 빼두면 된다.
@Configuration
public class FilterConfig {
@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/first-service/**")
.filters(f -> f.addRequestHeader("first-request", "first-request-header")
.addResponseHeader("first-response", "first--request-header"))
.uri("http://localhost:8081"))
.route(r -> r.path("/second-service/**")
.filters(f -> f.addRequestHeader("second-request", "second-request-header")
.addResponseHeader("second-response", "second--request-header"))
.uri("http://localhost:8082"))
.build();
}
}
따로 Config 파일을 만들고 그 안에 클래스를 생성해 주었다.
어노테이션을 활용해서 @Configuration
을 등록해 주면 서버를 시작할 때 자동으로 해당 클래스의 @Bean
을 등록해준다.
람다식을 사용해서 처리했는데 Filter()에서 RequestHeader
와 ResponseHeader
를 등록해주고 각 헤더에 담을 값도 입력해주었다. 각 헤더에 담길 값을 입력할 때는 Key-Value 형태로 입력을 해 주면 된다.
해석을 해 보면 .route(r -> r.path("/first-service/**")
에서 route를 하나 등록했고 완성이 되면 .uri("http://localhost:8081"))
으로 이동을 하겠다. 이런 말이다.
Controller에서는 위에 Filter에서 담은 헤더의 값을 확인해 볼 것이다.
@Slf4j
@RestController
@RequestMapping("/first-service")
public class FirstServiceController {
@GetMapping("/message")
public String message(@RequestHeader("first-request") String header) {
log.info("### header : {}", header);
return "Hello World in First Service.";
}
}
Filter에서 등록한 RequestHeader를 받아온다. ()
안에 받아올 헤더값의 이름은 first-service
이다.
요렇게 하고 서버를 돌려보면 정상적으로 헤더에 값을 받아오는 것을 확인할 수 있다. 지금 편의상 하나의 서비스에 대한 설정만 체크했는데 여러 서비스를 등록하고 테스트를 하면 확실한 결과를 체크해 볼 수 있다.