[Spring Boot] Spring Cloud Gateway에서 filter 사용하기-MSA(3)

모지리 개발자·2022년 9월 21일
2

MSA

목록 보기
3/9

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
를 수강하면서 작성한 글입니다.

먼저 프로세스를 이해하자

클라이언트는 원하는 서비스를 호출하기 위해 Spring Cloud gateway로 요청을 보냅니다. 그리고 Spring Cloud gateway에서는 어떤 서비스로 가야하는지 분기처리를 해줍니다. 위의 점선 네모 박스는 Spring Cloud gateway안에서 일어나는 일을 확대한 것입니다.

우선 요청이 들어오면 Gateway Handler Mapping 을 통해 클라이언트로부터 어떤 요청이 들어왔는지 정보를 받고 요청에 대한 사전 조건을 분기해주는 곳이 Predicate입니다.
그후 사전 Filter와 사후 Filter를 통해 요청정보를 구성할 수 있습니다.

Filter란?

디스패처 서블릿에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공합니다. 필터는 스프링 범위 밖에서 처리가 됩니다. 필터는 인터셉터와 비교해서 이해하는 것이 중요하므로 필터와 인터셉터 읽고 오시면 좋을 것 같습니다.

Filter 적용방법

filter를 적용하는 방법은 크게 2가지가 있습니다.
1. yml 파일을 통해 정의
2. java code를 통해 정의

JavaCode를 통한 Filter 만들기

우선 java code를 통해 Filter를 적용해보겠습니다.
yml 파일에 적혀있던 내용은 아래와 같이 주석처리하신다음에 시작하셔야합니다.

application.yml

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/**

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-request", "first-request-header")
                                .addResponseHeader("first-response", "first-response-header"))
                        .uri("http://localhost:8081"))
                .route(r -> r.path("/second-service/**")
                        .filters(f -> f.addRequestHeader("second-request", "second-request-header")
                                .addResponseHeader("second-response", "second-response-header"))
                        .uri("http://localhost:8082"))
                .build();
    }
}
  1. XXXX-service
    • /XXXX-service/** 에 들어오는 요청의 Request Header에는 XXXX-request : XXXX-request-header라는 값을 추가한다.
    • /XXXX-service/** 에 들어오는 응답의 Response Header에는 XXXX-resposne : XXXX-resposne-header라는 값을 추가한다.

first-service - FirstServiceController.java

@Slf4j
@RestController
@RequestMapping("/first-service")
public class FirstServiceController {

    @GetMapping("/welcome")
    public String welcome() {
        return "Welcome to the First service.";
    }

    @GetMapping("/message")
    public String message(@RequestHeader("first-request") String header) {
        log.info(header);
        return "Welcome to the Second service.";
    }
}

second-service - SecondServiceController.java

@Slf4j
@RestController
@RequestMapping("/second-service")
public class SecondServiceController {

    @GetMapping("/welcome")
    public String welcome() {
        return "Welcome to the Second service.";
    }

    @GetMapping("/message")
    public String message(@RequestHeader("second-request") String header) {
        log.info(header);
        return "Welcome to the Second service.";
    }
}

실행해보기

first-service 호출 시 아래와 같이 잘 호출됩니다.

reponse header에도 추가한 first-reponse가 잘 담겨서 왔습니다.

request header도 잘 출력되는 것을 볼 수 있습니다.

application.yml 을 통한 Filter 적용하기

우선 위에서 작성했던 FilterConfig.java 는 주석처리해주셔야합니다.

spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      routes:
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
          filters:
            - AddRequestHeader=first-request, first-request-header2
            - AddResponseHeader=first-response, first-response-header2
        - id: second-service
          uri: http://localhost:8082/
          predicates:
            - Path=/second-service/**
          filters:
            - AddRequestHeader=second-request, second-request-header2
            - AddResponseHeader=second-response, second-response-header2

이렇게 작성해주시면 위에서 JavaCode로 작성했던 Filter와 같은 기능을 합니다.

실행해보면 위에서와 같은 화면으로 동작하는 것을 볼 수 있습니다.

결론

Filter는

  • 공통된 보안 및 인증/인가 관련 작업
  • 모든 요청에 대한 로깅 또는 검사
  • 이미지/데이터 압축 및 문자열 인코딩
  • Spring과 분리되어야하는 기능

을 사용 할 때 자주 이용됩니다. MSA 프로젝트를 진행하면서 필터에 관해 추가할 내용이 있다면 더 추가해보도록 하겠습니다.

제가 잘못이해하고 있거나 잘못 작성한 부분이 있다면 지적, 비판, 피드백 뭐든 해주시면 감사하겠습니다!

profile
항상 부족하다 생각하며 발전하겠습니다.

0개의 댓글