2 분 소요

Spring Cloud Gateway에서 필터가 어떤한 동작에 의해 작동하는지, 프로세스를 살펴보자.

Filter의 프로세스

클라이언트가 First Service 혹은 Second Service를 사용하고 싶다고 할 때, Spring Cloud gateway가 중간에 자리잡고 있다.
클라이언트가 게이트웨이에 어떠한 요청을 전달하면, 게이트웨이에서 First Service로 갈 지 Second Service로 갈 지 판단 후에 서비스에 요청을 분기한다.
이 때, Spring Cloud gateway에서 일어나는 작업에 대해 더 자세히 알아보자.

스크린샷 2022-09-27 오전 12 04 43
첫 번째로, 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/messagehttp://localhost:8000/second-service/message에 접속해보자.

request header 확인

request는 인텔리제이의 콘솔 로그로 확인할 수 있다.
스크린샷 2022-09-27 오전 12 33 05

스크린샷 2022-09-27 오전 12 33 24

response header 확인

response는 cmd + option + i 단축키를 이용해 개발자 도구를 켜서 확인한다.
스크린샷 2022-09-27 오전 12 30 46

스크린샷 2022-09-27 오전 12 31 30

이렇게 게이트웨이에서 클라이언트의 요청을 중간에 가로채서, 추가적인 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/messagehttp://localhost:8000/second-service/message에 접속해보자. 스크린샷 2022-09-27 오전 1 11 04

스크린샷 2022-09-27 오전 1 11 38
마찬가지로 필터를 통해 헤더에 값이 잘 들어간 것을 확인할 수 있다.



💛 개인 공부 기록용 블로그입니다. 👻

맨 위로 이동하기