Spring Cloud Gateway's Route-Predicate-Filter Pipeline, End to End
Teams migrating from Spring Cloud Netflix to the current ecosystem hit immediate breakage: Ribbon is gone, Feign annotation rules are stricter, and reactive filter ordering is non-obvious. Getting the route-predicate-filter pipeline right determines whether a gateway becomes a clean traffic cop or a source of 404s, missing headers, and silent failures.
Spring Cloud Gateway acts as the single entry point for a microservice cluster, built on WebFlux's non-blocking reactive stack for higher concurrency. Its configuration model rests on three components: routes that point to backend services via `lb://` URIs, predicates that gate requests by path, header, cookie, time window, or custom query-parameter logic, and filters that process requests and responses before and after forwarding. A custom `VipRoutePredicateFactory` shows how to restrict access by matching query parameters, while a `OnceTokenGatewayFilterFactory` injects a UUID or JWT token into response headers after the chain completes.
Several sharp edges trip up new adopters. Spring Cloud has dropped Ribbon, so `spring-cloud-starter-loadbalancer` must be added manually for `lb://` to work. Feign interfaces annotated with `@FeignClient` break if you put `@RequestMapping` at the class level — path annotations belong only on methods. And reactive post-processing logic must live inside `chain.filter(exchange).then()` to mutate the response after it is built, not before.
Global CORS configuration moves cross-origin policy out of individual controllers and into the gateway, though production deployments should replace the `allowedOrigins: *` wildcard with explicit domains. The overall pattern pushes authentication, logging, rate limiting, and token issuance into the gateway layer, keeping downstream services focused on business logic.
Gateway configuration is declarative but fragile — a missing LoadBalancer dependency or a misplaced Feign annotation produces opaque 404s that are easy to misdiagnose.
The reactive programming model forces a specific mental model for filter ordering: anything that needs the finished response must run in a `then` callback, not inline.
Custom predicates and filters follow a factory pattern that is consistent but verbose; the `shortcutFieldOrder` list is easy to get wrong and silently breaks YAML parsing.
Moving cross-cutting concerns like CORS, auth tokens, and logging into the gateway reduces duplication but creates a new single point of failure that demands careful monitoring.
The `order` field on routes is optional but dangerous to omit — default top-down matching works until someone reorders the YAML file and breaks production routing.