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

Example: Configure gateway routes with predicates

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