Service Discovery & API Gateway
Spring Cloud Gateway — Dynamic Routing and Filters
Defining route predicates, rewrite paths, and injecting custom global headers.
Interview: API gateway design. Expect questions on WebFlux reactive models vs thread-blocking models, Route predicates logic, rewriting paths, and implementing custom GatewayFilters.
Introduction
Exposing multiple individual microservice ports directly to the internet is a security hazard. Clients would have to coordinate requests to separate endpoints (like http://api.company.com:8081 for payments and :8082 for catalog), complicating cross-origin (CORS) security rules.
**Spring Cloud Gateway** acts as the single entryway for all client requests. Built on Spring WebFlux, Project Reactor, and Netty, it routes requests dynamically to downstream services, handles path rewrites, and intercepts headers.
Why It Matters
API Gateways simplify client integrations, enforce security rules at the edge (such as JWT validation), and modify requests dynamically before they reach backend microservices.
Routes, Predicates, and Filters
Spring Cloud Gateway evaluates incoming requests using three core abstractions:
• Route: The primary component of the gateway. It is defined by an ID, a destination URI, predicates, and filters.
• Predicate: An evaluation statement (using Java 8 Predicates) that matches HTTP requests. Predicates can evaluate headers, paths, query parameters, or times.
• Filter: An interceptor (GatewayFilter) that allows modifying incoming requests or outgoing responses (e.g. adding request headers, rewriting URLs).
Practical Example
Let's write the configuration file for a gateway service routing traffic to order and payment services registered in Eureka:
Quick Quiz
Q1: What does the lb:// prefix in a route's target URI directive instruct Spring Cloud Gateway to do?
A) Route traffic over loopback interfaces.
B) Use client-side load-balancing to resolve the service name via Eureka instead of calling a static IP.
C) Compress the HTTP payload using gzip.
D) Redirect the request to an external load balancer.
Answer: B — The lb:// prefix enables integration with discovery registries, allowing the gateway to resolve service names and load-balance calls dynamically.
Scenario-Based Challenge
Production Scenario:
You want to track incoming requests as they travel through your microservices. You decide to generate a unique correlation ID at the gateway for every request and inject it as a header (X-Correlation-ID) before routing. How do you implement this?
To implement trace correlation at the edge:
1. **Create a Global Filter:** Implement a custom GlobalFilter bean in Java.
2. **Generate and Inject ID:** Generate a UUID and inject it into the request headers:
ServerHttpRequest mutatedRequest = exchange.getRequest().mutate()
.header("X-Correlation-ID", UUID.randomUUID().toString())
.build();
3. **Propagate:** Pass the mutated exchange down the filter chain:
return chain.filter(exchange.mutate().request(mutatedRequest).build());
Interview Questions
1. Why is Spring Cloud Gateway built on WebFlux instead of Spring MVC?
Spring MVC uses a blocking thread-per-request model. An API Gateway handles high concurrent traffic volumes, and blocking models can exhaust thread pools quickly. WebFlux uses a non-blocking, reactive event-loop architecture (via Netty), allowing a small thread pool to process thousands of concurrent connections efficiently.
Production Considerations
Configure CORS policies globally at the gateway layer. This prevents having to duplicate security configurations on individual microservices.