Spring Cloud Gateway: Reactive API Routing
Spring Cloud Gateway provides a reactive, non-blocking API gateway built on Spring WebFlux that handles routing, filtering, and cross-cutting concerns for microservices architectures. Therefore, it serves as the single entry point for all client requests while performing authentication, rate limiting, and request transformation. As a result, backend services remain focused on business logic without duplicating infrastructure concerns.
Route Configuration and Predicates
Routes define the mapping between incoming requests and downstream services using predicates and filters. Moreover, predicates match requests based on path patterns, headers, query parameters, and custom conditions. Consequently, complex routing rules can be expressed declaratively in YAML or programmatically in Java.
Predicate factories combine with logical AND/OR operators for sophisticated matching. Furthermore, weight-based routing enables canary deployments by splitting traffic between service versions based on configurable percentages.
Custom Filters for Spring Cloud Gateway
Gateway filters modify requests and responses as they pass through the gateway. Additionally, pre-filters execute before forwarding to the backend while post-filters process the response before returning to the client. For example, a pre-filter can add authentication headers while a post-filter removes internal headers from the response.
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route("order-service", r -> r
.path("/api/orders/**")
.filters(f -> f
.stripPrefix(1)
.addRequestHeader("X-Gateway", "spring-cloud")
.retry(config -> config
.setRetries(3)
.setStatuses(HttpStatus.SERVICE_UNAVAILABLE))
.circuitBreaker(config -> config
.setName("orderCB")
.setFallbackUri("forward:/fallback/orders"))
.requestRateLimiter(config -> config
.setRateLimiter(redisRateLimiter())
.setKeyResolver(userKeyResolver())))
.uri("lb://order-service"))
.route("product-service", r -> r
.path("/api/products/**")
.filters(f -> f
.stripPrefix(1)
.cacheRequestBody(String.class))
.uri("lb://product-service"))
.build();
}
@Bean
public RedisRateLimiter redisRateLimiter() {
return new RedisRateLimiter(10, 20, 1);
}
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getHeaders()
.getFirst("X-User-Id"));
}
}The circuit breaker filter prevents cascading failures when downstream services are unhealthy. Therefore, requests fail fast with fallback responses rather than queuing behind an unresponsive service.
Rate Limiting and Security
Redis-backed rate limiting tracks request counts per client key across gateway instances. However, choosing the right key resolver determines the granularity of rate limiting. In contrast to IP-based limiting, user-based or API-key-based limiting provides fairer distribution for clients behind shared proxies.
Production Monitoring
Enable Micrometer metrics for gateway routes to track latency percentiles, error rates, and throughput per route. Additionally, distributed tracing with OpenTelemetry propagates trace context through the gateway to downstream services for end-to-end visibility.
Related Reading:
Further Resources:
In conclusion, Spring Cloud Gateway provides reactive routing, filtering, and resilience patterns essential for production microservices architectures. Therefore, adopt it as your API gateway to centralize cross-cutting concerns and simplify backend service development.