Spring Cloud Gateway is a powerful, non-blocking API gateway built on top of Project Reactor, Spring WebFlux, and Spring Boot 2+. It replaces Netflix Zuul as the preferred gateway in modern microservice architectures.
🚪 What Is an API Gateway?
An API Gateway is a server that sits in front of microservices and:
- Routes requests to appropriate services.
- Handles cross-cutting concerns: authentication, rate limiting, logging, and more.
- Enables client-side abstraction from service internals.
✅ Why Spring Cloud Gateway?
- Reactive and performant
- Route configuration via code or config file
- Built-in support for filters, predicates
- Easier to use than Zuul 1
- Integrates well with Spring Cloud ecosystem
📦 1. Setup Spring Cloud Gateway
🔸 pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
⚙️ 2. Basic Routing via application.yml
spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/users/**
- id: order-service
uri: http://localhost:8082
predicates:
- Path=/orders/**
🧠 Explanation:
id
: unique name for the routeuri
: target microservicepredicates
: conditions likePath
,Header
,Method
, etc.
🚥 3. Route Predicates
Predicate | Usage Example |
---|---|
Path | /api/** , /users/** |
Method | GET , POST , etc. |
Header | Match on headers |
Query | Match query params |
Cookie | Match specific cookie |
After , Before , Between | Time-based predicates |
🧹 4. Global Filters
Filters are used to modify requests/responses before or after routing.
Example: Adding a Global Logging Filter
@Component
public class LoggingFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("Request URI: " + exchange.getRequest().getURI());
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1; // priority
}
}
🔄 5. Custom Gateway Filters
Create filters for authentication, logging, transformation, etc.
Example: Add custom header
@Component
public class AddHeaderFilterFactory extends AbstractGatewayFilterFactory<AddHeaderFilterFactory.Config> {
public AddHeaderFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
exchange.getRequest().mutate()
.header(config.name, config.value)
.build();
return chain.filter(exchange);
};
}
public static class Config {
private String name;
private String value;
// getters/setters
}
}
Usage in application.yml
filters:
- name: AddHeader
args:
name: X-Custom-Header
value: GatewayHeader
🔐 6. Authentication via Filters
Use pre-filters to check JWT or API keys.
@Component
public class AuthFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
}
🛡️ 7. CORS Configuration
To allow cross-origin requests:
@Configuration
public class CorsConfig {
@Bean
public WebFluxConfigurer corsConfigurer() {
return new WebFluxConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*");
}
};
}
}
🌐 8. API Gateway with Eureka (Optional)
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
Enable Eureka client in Gateway app:
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
Now uri: lb://user-service
works automatically.
🧪 9. Test It
- Run two mock services on port 8081 and 8082
- Access
http://localhost:8080/users/all
- Gateway will route to the user-service
🧰 Tools You Can Combine
- Swagger aggregation (using custom UIs or redirect paths)
- JWT Authentication using filters
- Rate Limiting using Spring Cloud Gateway Redis support
- Circuit Breaker with Resilience4j or Hystrix
🧠 Summary
Feature | Description |
---|---|
Reactive routing | High-performance routing layer |
Predicate-based | Path, Method, Header-based routing |
Filter system | Modify request/response easily |
Discovery support | Works with Eureka and Consul |
Extensible | Add custom filters for auth/logging/metrics |
➡️ Next Up: Part 21 – Resilience with Circuit Breakers and Retry Mechanisms (Resilience4j)