Understanding Spring Cloud Gateway Architecture and Implementation

Core Components of Spring Cloud Gateway

  • Route: The fundamental building block of the gateway, consisting of an identifier, destination URI, predicates, and filters. When a request reaches the gateway, the Gateway Handler Mapping evaluates routes based on predicates. When a predicate returns true, the corresponding route is selected for forwarding.
  • Predicate: Enables developers to match elements within HTTP requests. Once a predicate evaluates to true, the appropriate route is selected for forwarding.
  • Filter: Allows for business logic processing before and after request transmission, such as authentication, monitoring, rate limiting, and more.

The overall operational flow is as follows: Predicates act as matching conditions, while filters functon as versatile interceptors. Together with the target URI, they form a complete routing mechanism.

When a client makes a request to Spring Cloud Gateway, if the request matches a defined route, it's sent to the gateway's Web handler. The handler then executes a specific filter chain. Filters are separated by dashed lines because they may execute logic before and after the proxy request. All pre-filter logic runs first, followed by the proxy request, and finally, the post-filter logic executes after the proxy request completes.

Filter Categories

  • GlobalFilter
  • RouteFilter

AddRequestParameter GatewayFilter Factory

This filter adds specified parammeters to the request. The configuration AddRequestParameter=param, blue adds a parameter with key "param" and value "blue". The first path segment "gateway" is stripped.

spring:
  application:
    name: spring-cloud-gateway
  cloud:
    gateway:
      routes:
        - id: add_request_parameter_route
          predicates:
            - Path=/gateway/**
          uri: http://localhost:8082/
          filters:
            - StripPrefix=1
            - AddRequestParameter=param, blue

RequestRateLimiter GatewayFilter Factory

This filter implements rate limiting for all requests reaching the gateway. When rate limiting is applied, it responds with HTTP 429 - Too Many Requests by default. RequestRateLimiterGatewayFilterFactory provides RedisRateLimiter implementation, which uses the token bucket algorithm for rate limiting.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

@Component
public class ClientAddressKeyResolver implements KeyResolver {

    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }
}

spring:
  cloud:
    gateway:
        routes: 
        - id: rate_limiter_route
          predicates:
            - Path=/rate_limit/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
            args:
              deny-empty-key: true
              keyResolver: '#{@clientAddressKeyResolver}'
              redis-rate-limiter.replenishRate: 1
              redis-rate-limiter.burstCapacity: 2
          uri: lb://order-service

The redis-rate-limiter filter has two configuration properties that align with the token bucket concept:

  • replenishRate: The rate at which tokens are added to the bucket, representing the number of requests allowed per second.
  • burstCapacity: The maximum capacity of the token bucket, representing the maximum number of requests a user can make per second.

Retry GatewayFilter Factory

This filter enables request retry mechanisms when backend services are unavailable. The gateway initiates retry requests based on configured parameters.

spring:
  cloud:
    gateway:
      routes:
      - id: retry_route
        uri: http://www.example.com
        predicates:
        - Path=/example/**
        filters:
        - name: Retry
          args:
            retries: 3
            status: 503
        - StripPrefix=1

RetryGatewayFilter provides four parameters to control retry behavior:

  • retries: Number of retry attempts, default is 3.
  • status: HTTP status codes that trigger retries. Multiple status codes can be specified. In the example above, retries occur when the server returns status 503.
  • methods: Specifies HTTP methods that should be retried, default is GET.
  • series: Configures error code ranges for retries. Default is SERVER_ERROR(5), meaning all 5xx status codes trigger retries. If series is configured but status is not, it will still match based on series for retries.

Custom Predicate Implementation

To create custom predicates, extend the AbstractRoutePredicateFactory class:

@Component
public class AuthorizationRoutePredicateFactory extends AbstractRoutePredicateFactory<AuthorizationRoutePredicateFactory.Config> {

    public AuthorizationRoutePredicateFactory() {
        super(Config.class);
    }

    private static final String HEADER_NAME_KEY = "headerName";
    private static final String HEADER_VALUE_KEY = "headerValue";

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(HEADER_NAME_KEY, HEADER_VALUE_KEY);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // Checks if the request header contains a specific value
        return exchange -> {
            HttpHeaders headers = exchange.getRequest().getHeaders();
            List<String> headerValues = headers.get(config.getHeaderName());
            return headerValues != null && !headerValues.isEmpty();
        };
    }

    public static class Config {
        private String headerName;
        private String headerValue;

        public String getHeaderName() {
            return headerName;
        }

        public void setHeaderName(String headerName) {
            this.headerName = headerName;
        }

        public String getHeaderValue() {
            return headerValue;
        }

        public void setHeaderValue(String headerValue) {
            this.headerValue = headerValue;
        }
    }
}

spring:
  cloud:
    gateway:
      routes:
      - id: authorization_route
        predicates:  
          - Authorization=Authorization,token
        filters:
          - StripPrefix=1
        uri: https://www.example.com

Custom Filter Implementation

To create custom filters, extend the AbstractGatewayFilterFactory class:

@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.CustomConfig> {

    private static final String PARAM_NAME_KEY = "paramName";

    private final Logger logger = LoggerFactory.getLogger(CustomGatewayFilterFactory.class);

    public CustomGatewayFilterFactory() {
        super(CustomConfig.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PARAM_NAME_KEY);
    }

    @Override
    public GatewayFilter apply(CustomConfig config) {
        // Filter with pre and post phases
        return (exchange, chain) -> {
            logger.info("[Pre-filter] Processing request, parameter: " + config.getParamName());
            // Custom pre-processing logic
            
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // Custom post-processing logic
                logger.info("[Post-filter] Processing response");
            }));
        };
    }

    public static class CustomConfig {
        private String paramName;

        public String getParamName() {
            return paramName;
        }

        public void setParamName(String paramName) {
            this.paramName = paramName;
        }
    }
}

spring:  
  cloud:
    gateway:
      routes:
        - id: custom_route
          predicates:
            - Path=/gateway/**
          filters:
            - StripPrefix=1
            - Custom=Hello world
          uri: http://localhost:8082/

Gateway Configuration Verification

To view the gateway's route configuration, access the following endpoint:

http://ip:port/actuator/gateway/routes

Tags: Spring Cloud Gateway microservices Reactive Programming java

Posted on Thu, 11 Jun 2026 17:36:56 +0000 by RecoilUK