1. 들어가며
마이크로서비스 아키텍처를 구축하다 보면 여러 개의 독립된 서비스가 생기고,
각 서비스마다 클라이언트가 직접 접근하도록 두는 건 보안, 버전 관리, 로드밸런싱 측면에서 매우 비효율적이다.
그래서 모든 외부 요청을 하나의 진입점을 통해 받아서 내부 서비스로 분기시키는 패턴이 등장했는데, 그게 바로 API Gateway다.
Spring Cloud에서 공식적으로 지원하는 Gateway 컴포넌트인 Spring Cloud Gateway는 이 역할을 수행하기에 최적화된 도구다.
2. Spring Cloud Gateway란?

Spring Cloud Gateway는 스프링 생태계에서 API Gateway 역할을 수행하는 프로젝트로, 기존 Zuul 1의 한계를 개선하여 WebFlux 기반으로 만들어졌다. 이는 비동기 논블로킹 방식으로 동작하여 성능상 이점이 있고, Spring Cloud와의 자연스러운 통합을 통해 Eureka, Config Server, Bus, Security 등과 손쉽게 연계할 수 있다.

Gateway는 클라이언트의 모든 요청을 받아서 적절한 서비스로 라우팅하며, 이 과정에서 다양한 전처리(Pre-filter), 후처리(Post-filter) 작업도 수행할 수 있다.
3. 기본 설정과 구조
3.1 의존성 추가
먼저 Spring Cloud Gateway를 사용하려면 다음과 같은 의존성을 추가해야 한다.
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}
Eureka Client를 함께 추가하는 이유는, 마이크로서비스 주소를 직접 쓰는 대신 Eureka에 등록된 서비스 이름을 사용하여 동적으로 라우팅하기 위해서이다.
3.2 application.yml
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/users/**
filters:
- AddRequestHeader=X-Gateway, SpringCloudGateway
discovery:
locator:
enabled: true
lower-case-service-id: true
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
이 설정의 핵심은 lb://user-service 라는 주소다.
이건 실제 물리적 주소가 아니라, Eureka에 등록된 논리적 서비스 이름이다.
즉, Gateway가 직접 IP나 포트를 몰라도, Eureka를 통해 요청을 적절한 인스턴스로 전달할 수 있게 된다.
4. 주요 개념
4.1 Predicate (경로 조건)
Gateway는 Predicate를 통해 어떤 요청을 어떤 서비스로 보낼지를 판단한다.
대표적인 조건으로는 Path, Method, Header, Host, Query 등이 있다.
예를 들어, /users/** 경로로 들어오는 요청은 모두 user-service로 보내도록 설정할 수 있다.
4.2 Filter (요청/응답 가공)
Filter는 요청을 변경하거나 응답을 수정하는 기능을 한다.
- Pre Filter: 요청에 Header를 추가하거나 인증 토큰을 검증
- Post Filter: 응답 로그 기록, 응답 데이터 후처리 등
filters:
- name: AddRequestHeader
args:
name: X-Gateway
value: SpringCloudGateway
커스텀 필터를 만들어서 Java 코드로 제어하는 것도 가능하다.
5. 커스텀 필터 구현 예시
@Component
public class LoggingFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Request path: " + exchange.getRequest().getPath());
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
이 필터는 모든 요청 경로를 로그로 출력하고, 그 다음 필터 체인으로 넘긴다.
이처럼 공통 로깅, 트래픽 제한, 인증 처리 등을 필터로 분리할 수 있어서 매우 유연하게 확장이 가능하다.
6. Eureka와 Gateway의 통합
Spring Cloud Gateway는 Eureka와 통합되어, 등록된 서비스 이름을 기반으로 자동 라우팅도 가능하다.
discovery:
locator:
enabled: true
이 설정을 통해 routes를 명시적으로 설정하지 않아도, Eureka에 등록된 모든 서비스에 대해 자동으로 경로를 생성해준다.
예를 들어, http://localhost:8080/user-service/**로 요청하면 해당 경로는 자동으로 user-service로 전달된다.
이 기능은 빠르게 API Gateway를 구성할 때 유용하지만, 보안이나 정책 관리를 위해 실무에선 수동 라우팅 설정을 선호한다고 한다.
7. 마무리
Spring Cloud Gateway는 마이크로서비스의 진입점 역할을 수행하면서 다양한 라우팅, 필터링, 인증 처리, 트래픽 제어 등을 담당할 수 있는 강력한 도구다. 특히 Eureka, Config, Feign, Bus 등 Spring Cloud 생태계와 잘 통합되어 있어, Spring 기반의 마이크로서비스 시스템을 구축할 때 매우 유용하다.
각 서비스의 세부 구현보다 더 중요한, 서비스 간 통신 구조와 흐름 제어, 공통 로직 처리, 요청/응답 가공 등을 Gateway에서 효과적으로 관리해볼 수 있었다.