Spring cloud gateway는 Spring boot, Spring webflux, Reactor를 사용하여 만들어진 Spring 진영의 Api gateway 프레임워크이다.
Spring webflux를 사용하므로 높은 처리량을 보여주며, Spring Circuit Breaker도 지원하고 있어서 높은 안정성을 보장한다.
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/user/**
filters:
- AddRequestHeader=X-Request-User, GatewayUser
- AddResponseHeader=X-Response-Time, 100ms
- RewritePath=/user/(?<segment>.*), /api/users/$\{segment}
Spring cloud gateway의 가장 기본적인 기능인 '라우팅'은 클라이언트의 요청을 적절한 마이크로 서비스로 전달하는 기능을 의미한다.
엔드포인트를 통한 기본적인 라우팅은 물론이고, Predicate
를 사용해서 다양한 조건의 라우팅을 만들어줄 수 있다.
Spring cloud gateway는 API Gateway로써, 하위에 여러 마이크로 서비스를 갖고 있다는 특징으로 인해서 클라이언트의 요청을 마이크로 서비스로 전달하기 전에 공통된 어떤 처리가 가능해진다.
대표적으로, 공통적으로 적용할 '필터'를 적용할 수 있고, 로깅, 요청 변환, CORS 처리, 속도 제한, 인증/인가 등등의 처리가 가능하다.
plugins {
id 'org.springframework.boot' version '3.2.2'
id 'io.spring.dependency-management' version '1.1.3'
id 'java'
}
group = 'com.example'
version = '1.0.0'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2023.0.0"
}
}
Spring cloud 계열의 라이브러리/프레임워크의 경우 spring-cloud-dependencies
에 명시된 버전을 따라가므로, spring-cloud-dependencies
를 mavenBom
으로 명시해준다.
server:
port: 8080
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/api/users/**
filters:
- AddRequestHeader=X-Request-Gateway, MyGateway
- AddResponseHeader=X-Response-Gateway, ProcessedByGateway
- RewritePath=/api/users/(?<segment>.*), /users/${segment}
Spring cloud gateway의 경우 라우팅 및 필터를 설정하는 방법을 yaml
기반 또는 Configuration 클래스 기반의 방식을 제공한다.
지금은 yaml
파일을 작성하였지만, 이 것과 동일한 설정을 Configuration 클래스로 그대로 작성해줄 수도 있다.
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import reactor.core.publisher.Mono;
public class AuthenticationFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// Authorization 헤더 확인
String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");
// 헤더가 없거나 유효하지 않은 경우 401 반환
if (authHeader == null) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 유효한 경우 다음 필터 체인으로 전달
return chain.filter(exchange);
}
// 필터의 실행 순서를 지정
@Override
public int getOrder() {
return -1; // 다른 필터보다 먼저 실행하도록 설정
}
}
Spring security를 사용할 때 자주 볼 수 있는 스타일로 인증/인가 필터를 만들고, 아래와 같이 필터를 등록해줄 수 있다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GatewayFilterConfig {
@Bean
public AuthenticationFilter authenticationFilter() {
return new AuthenticationFilter();
}
}