1. API 게이트웨이란 무엇일까?
- 클라이언트의 요청을 받아 백엔드 서비스로 라우팅하고, 다양한 부가 기능을 제공한다.
- 클라이언트와 서비스 간의 단일 진입점 역할을 하며, 라우팅, 인증 & 권한 부여, 로드 밸런싱, 모니터링 & 로깅, 요청 & 응답 변환 등을 처리한다.
2. Spring Cloud Gateway란 무엇일까?
- Spring에서 개발된 API 게이트웨이로, 클라이언트 요청을 적절한 서비스로 라우팅하고 다양한 필터링 기능을 제공한다.
- 주요 기능으로 동적 라우팅, 필터링, 모니터링, 보안 등의 역할을 수행한다.

사용자는 각각의 URL에 따라 데이터를 요청하지않고, 하나의 URL을 통해 API Gateway에 요청을 하면 API Gateway는 인증, 인가, 요청, 응답 등을 수행하여 사용자가 원하는 데이터를 제공해주는 역할을 한다.
3. Spring Cloud Gateway 필터링
- Global Filter: 모든 요청에 대해 작동하는 필터
- Gateway Filter: 특정 라우터에만 적용되는 필터
필터 시점별 종류
- Pre 필터: 요청이 처리되기 전에 실행되는 필터로, 요청을 가로채고 필요한 작업을 수행한 뒤, 체인의 다음 필터로 요청을 전달한다.
- Post 필터: 요청이 처리된 후, 응답이 반환되기 전에 실행된다(데이터를 가져온 뒤 실행). Post 필터에서는 체인의 다음 필터가 완료된 후에 실행되어야 하는 추가적인 작업을 수행해야 하기 때문에, chain.filter(exchange)를 호출하여 다음 필터를 실행한 후, then 메서드를 사용하여 응답이 완료된 후 실행할 작업을 정의하는 방식으로 진행된다.
4. API Gateway 구현
Gateway
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway-server-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-actuator-test'
testImplementation 'io.projectreactor:reactor-test'
testCompileOnly 'org.projectlombok:lombok'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testAnnotationProcessor 'org.projectlombok:lombok'
}
CustomPostFilter.java
package com.springcloud.client.gateway;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.logging.Logger;
@Component
public class CustomPostFilter implements GlobalFilter, Ordered {
private static final Logger logger = Logger.getLogger(CustomPostFilter.class.getName());
@Override
public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
logger.info("Post Filter: Response status code is " + response.getStatusCode());
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
CustomPreFilter.java
package com.springcloud.client.gateway;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.logging.Logger;
@Component
public class CustomPreFilter implements GlobalFilter, Ordered {
private static final Logger logger = Logger.getLogger(CustomPreFilter.class.getName());
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest response = exchange.getRequest();
logger.info("Pre Filter: Request URI is " + response.getURI());
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
application.yml
server:
port: 19091 # 게이트웨이 서비스가 실행될 포트 번호
spring:
main:
web-application-type: reactive # Spring 애플리케이션이 리액티브 웹 애플리케이션으로 설정됨
application:
name: gateway-service # 애플리케이션 이름을 'gateway-service'로 설정
cloud:
gateway:
routes: # Spring Cloud Gateway의 라우팅 설정
- id: order-service # 라우트 식별자
uri: lb://order-service # 'order-service'라는 이름으로 로드 밸런싱된 서비스로 라우팅
predicates:
- Path=/order/** # /order/** 경로로 들어오는 요청을 이 라우트로 처리
- id: product-service # 라우트 식별자
uri: lb://product-service # 'product-service'라는 이름으로 로드 밸런싱된 서비스로 라우팅
predicates:
- Path=/product/** # /product/** 경로로 들어오는 요청을 이 라우트로 처리
discovery:
locator:
enabled: true # 서비스 디스커버리를 통해 동적으로 라우트를 생성하도록 설정
eureka:
client:
service-url:
defaultZone: http://localhost:19090/eureka/ # Eureka 서버의 URL을 지정
본 설정을 통해 Spring Cloud Gateway와 Eureka Service Discovery의 연동을 완료했습니다. 이를 통해 클라이언트는 각 마이크로서비스(Order, Product)의 실제 IP나 포트 번호를 알 필요 없이, Gateway(Port: 19091)라는 하나의 단일 창구(Single Entry Point)를 통해 내부 애플리케이션에 안전하게 접근할 수 있게 되었습니다.
이 구조에서 Gateway는 시스템의 최전방에서 동적 라우팅, 로드 밸런싱, 그리고 공통 필터링(Pre/Post Filter)을 수행하는 중추적인 역할을 담당합니다.
'MSA' 카테고리의 다른 글
| Config(Spring Cloud Config) (0) | 2026.06.29 |
|---|---|
| 보안 구성 (0) | 2026.06.28 |
| 서킷 브레이커 (Resilience4j) (0) | 2026.06.27 |
| 로드 밸런싱 (0) | 2026.06.26 |
| 서비스 디스커버리 (Eureka) 와 Server/Client 설정 방법 (0) | 2026.06.26 |