Spring Cloud Gateway

Spring Cloud Gateway

A reactive API gateway built on Spring WebFlux and Project Reactor, serving as the standard Spring-ecosystem foundation for BFF and API gateway implementations.


Core Idea

Spring Cloud Gateway (SCG) is the recommended replacement for Netflix Zuul in the Spring Cloud ecosystem. It processes HTTP requests through a Route → Predicate → Filter pipeline running entirely on a non-blocking Netty event loop. Every operation is modelled as a Mono<Void> or Flux<T>, enabling high concurrency without thread-per-request overhead.

SCG is the natural foundation for the BFF-Pattern because its filter model directly encodes BFF responsibilities: routing by client type, transforming request/response shapes, enforcing authentication, and aggregating downstream calls.


Key Principles

  1. Everything is non-blocking — SCG runs on Reactor Netty; no Servlet API, no blocking I/O anywhere in the request path.
  2. Route = id + URI + predicates + filters — this three-part structure handles routing logic declaratively in application.yml or programmatically via RouteLocatorBuilder.
  3. ServerWebExchange is the mutable context — all filters read and write through this object; request mutations require calling .mutate() to produce a new immutable copy.

How It Works

The Request Pipeline

Client Request
    │
    ▼
[GlobalFilters] (ordered, apply to ALL routes)
    │
    ▼
[Predicate matching] (finds first matching Route)
    │
    ▼
[Route GatewayFilters] (pre-processing)
    │
    ▼
[Downstream Service]
    │
    ▼
[Route GatewayFilters] (post-processing, reverse order)
    │
    ▼
[GlobalFilters] (post-processing, reverse order)
    │
    ▼
Client Response

Route Definition (YAML)

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service          # load-balanced URI
          predicates:
            - Path=/api/users/**          # match by path
            - Method=GET,POST             # match by method
          filters:
            - StripPrefix=1               # remove /api prefix
            - TokenRelay=                 # forward OAuth2 token
            - name: CircuitBreaker
              args:
                name: userCB
                fallbackUri: forward:/fallback/users

Route Definition (Java DSL)

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("user-service", r -> r
            .path("/api/users/**")
            .filters(f -> f
                .stripPrefix(1)
                .addRequestHeader("X-BFF-Source", "gateway")
                .circuitBreaker(c -> c.setName("userCB")
                    .setFallbackUri("forward:/fallback/users")))
            .uri("lb://user-service"))
        .build();
}

Predicate Types

PredicateMatches on
PathURL path pattern
MethodHTTP method
HeaderRequest header (regex)
QueryQuery parameter
HostHostname pattern
CookieCookie value
After/Before/BetweenTime window
RemoteAddrClient IP/CIDR
WeightWeighted group (canary)

Filter Types

FilterEffect
AddRequestHeader / AddResponseHeaderInject headers
RemoveRequestHeaderStrip headers (security)
RewritePathRegex URL rewrite
StripPrefixRemove path prefix segments
TokenRelayForward OAuth2 token downstream
CircuitBreakerResilience4j circuit breaker
RetryRetry on failure
RequestRateLimiterRedis-backed rate limiting
DedupeResponseHeaderRemove duplicate response headers

Examples

  • BFF route with auth: Route /api/mobile/** to mobile-specific microservice endpoints, strip the /api/mobile prefix, relay the OAuth2 token, and apply a circuit breaker with a cached fallback response.
  • Canary deployment: Use Weight predicate to send 90% of traffic to user-service-v1 and 10% to user-service-v2.
  • Global correlation ID: Implement a GlobalFilter that injects X-Correlation-Id on every request (see P2-Spring-Boot-BFF-Stack Example 3).

Common Misconceptions

  • SCG can run on Spring MVC (Servlet): The standard spring-cloud-starter-gateway requires WebFlux. A separate spring-cloud-starter-gateway-mvc exists for servlet use, but it loses the non-blocking properties.
  • SCG replaces all microservice logic: SCG is a routing/filtering layer. Aggregation logic that requires calling multiple services and merging belongs in a custom @RestController or service class, not in built-in filters.
  • GlobalFilter runs once: GlobalFilters run for every matched route, in getOrder() sequence. Pre-processing happens in ascending order, post-processing in descending order.

Why It Matters

For a BFF-Pattern implementation, SCG provides:

  • Per-client routing without code changes (YAML-driven)
  • Auth enforcement at the gateway layer (token validation + relay)
  • Resilience patterns (circuit breaker, retry, rate limiting) without modifying downstream services
  • Actuator endpoints for live route inspection: GET /actuator/gateway/routes

ConceptRelationship
BFF-PatternSCG is the primary implementation vehicle
API-Gateway-PatternSCG is a specialised API gateway
Project-ReactorSCG uses Reactor for all async processing
Reactive-ProgrammingSCG requires reactive programming model
Token-Relay-PatternSCG's TokenRelay filter implements this
Request-AggregationCustom controllers behind SCG implement this

Version Reference

Spring BootSpring CloudSCG Version
3.2.x / 3.3.x2023.0.x (Leyton)4.1.x
3.4.x2024.0.x (Moore)4.2.x

Current recommended (2025/2026): Spring Boot 3.4.x + Spring Cloud 2024.0.x


Sources

  • spring.io/projects/spring-cloud-gateway (official reference)
  • Spring Cloud 2024.0 release notes
  • P2-Spring-Boot-BFF-Stack (Phase 2 research)