Working with API Gateway
1. Setting Up Spring Cloud Gateway
Example: API Gateway dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Warning: Spring Cloud Gateway is reactive (WebFlux). Do NOT add
spring-boot-starter-web in the same module.
2. Configuring Route Definitions
spring:
cloud:
gateway:
routes:
- id: orders-route
uri: lb://orders
predicates:
- Path=/api/orders/**
filters:
- StripPrefix=1
- id: users-route
uri: http://user-svc:8080
predicates:
- Path=/api/users/**
3. Using Predicates for Route Matching
| Predicate |
Example |
| Path |
Path=/api/** |
| Method |
Method=GET,POST |
| Host |
Host=**.example.com |
| Header |
Header=X-Tenant, .* |
| Query |
Query=type, premium |
| Cookie |
Cookie=session, .+ |
| After / Before / Between |
Time-based |
4. Implementing Route Filters
Example: Define routes via Java DSL
@Bean
RouteLocator routes(RouteLocatorBuilder b) {
return b.routes()
.route("orders", r -> r.path("/api/orders/**")
.filters(f -> f.stripPrefix(1).addRequestHeader("X-Source", "gateway"))
.uri("lb://orders"))
.build();
}
5. Using Built-in Filters
| Filter |
Use |
StripPrefix=1 |
Remove path segments |
PrefixPath=/v2 |
Add prefix |
RewritePath=/x/(?<p>.*), /$\{p} |
Regex rewrite |
AddRequestHeader / AddResponseHeader |
Inject headers |
Retry=3 |
Retry on failure |
CircuitBreaker=name |
Wrap with CB |
RequestRateLimiter=... |
Redis rate limiter |
SetStatus=404 |
Override response status |
6. Creating Custom Gateway Filters (GatewayFilter)
Example: Inject correlation ID at gateway
@Component
public class CorrelationIdFilter implements GlobalFilter, Ordered {
@Override public Mono<Void> filter(ServerWebExchange exch, GatewayFilterChain chain) {
String id = Optional.ofNullable(exch.getRequest().getHeaders().getFirst("X-Correlation-Id"))
.orElse(UUID.randomUUID().toString());
ServerHttpRequest mutated = exch.getRequest().mutate().header("X-Correlation-Id", id).build();
return chain.filter(exch.mutate().request(mutated).build());
}
@Override public int getOrder() { return -1; }
}
7. Implementing Rate Limiting at Gateway
Example: Gateway rate limiter with Redis key resolver
spring:
cloud:
gateway:
routes:
- id: orders
uri: lb://orders
predicates: [ Path=/api/orders/** ]
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
key-resolver: "#{@principalKeyResolver}"
Example: Rate limit key resolver by principal
@Bean
KeyResolver principalKeyResolver() {
return ex -> ex.getPrincipal().map(Principal::getName).defaultIfEmpty("anonymous");
}
8. Configuring CORS at Gateway Level
Example: Global CORS at gateway level
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "https://app.example.com"
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
max-age: 3600
9. Implementing Authentication at Gateway
Example: Gateway JWT security filter chain
@Bean
SecurityWebFilterChain security(ServerHttpSecurity http) {
return http
.authorizeExchange(a -> a
.pathMatchers("/actuator/health", "/api/public/**").permitAll()
.anyExchange().authenticated())
.oauth2ResourceServer(r -> r.jwt(Customizer.withDefaults()))
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.build();
}
10. Testing Gateway Routes and Filters
Example: Test gateway route and response headers
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class GatewayRouteTests {
@Autowired WebTestClient client;
@Test void routesOrders() {
client.get().uri("/api/orders/1").exchange()
.expectStatus().isOk()
.expectHeader().exists("X-Correlation-Id");
}
}
11. Using Gateway with Service Discovery
Example: Auto-route via service discovery
spring:
cloud:
gateway:
discovery:
locator:
enabled: true # auto-route /service-name/**
lower-case-service-id: true