Build a Minimal Spring Cloud Gateway with Controller‑Based Routing
This article explains how to use Spring Cloud Gateway 3.1.5 to create a lightweight API gateway by configuring routes in YAML and implementing routing logic directly in a Spring MVC or WebFlux controller with ProxyExchange, covering features, code examples, and dynamic path mapping.
Spring Cloud Gateway 3.1.5 is a reactive, high‑performance API gateway built on Spring Framework 5, Spring Boot 2 and Project Reactor, providing routing, load‑balancing, security, rate limiting, circuit breaking and seamless integration with other Spring Cloud components.
Reactive non‑blocking model for high throughput and low latency.
Multiple routing predicates (path, query, header, host, etc.).
Global and custom filters for request/response manipulation.
Dynamic route and filter configuration at runtime.
Integration with Spring Cloud Discovery for service‑registry‑based routing.
Integration with Spring Cloud Security for authentication and authorization.
Integration with Spring Cloud Circuit Breaker for fault tolerance.
Integration with Spring Cloud Stream for event‑driven architectures.
Extensible with other Spring Cloud components such as Netflix, Consul, Zookeeper.
Typical gateway configuration is done in application.yml (or application.properties ) and requires only a few lines to enable the gateway and define routes.
<code>spring:
cloud:
gateway:
enabled: true
discovery:
locator:
# Enable service‑name based route discovery
enabled: true
lowerCaseServiceId: true
# Default filters applied to all routes
default-filters:
- StripPrefix=1
routes:
- id: alibaba
# Load‑balance via service discovery
uri: lb://cloudAlibaba
predicates:
- name: Path
args:
a: /api-1/**
- id: ooxx
uri: http://www.baidu.com
predicates:
- Path=/api-x/**
- id: xxoo
uri: http://localhost:8082
predicates:
- Path=/api-x/**
- Host=localhost:9099
- Weight=G1, 5
</code>For ultra‑simple scenarios you can avoid a separate gateway service and implement routing directly in a controller using the ProxyExchange utility. The following example shows a Spring MVC controller that forwards a request to a downstream service, adds a custom header, and returns a static response.
<code>@RestController
@RequestMapping("/proxy/api")
public class GatewayController {
@GetMapping("")
public Object order(@RequestHeader("token") String token,
Integer id,
ProxyExchange<Map<String, Object>> exchange) {
Map<String, Object> body = new HashMap<>();
body.put("id", id);
body.put("token", token);
return exchange.uri("http://localhost:9000/business/index")
.header("key", "123123")
.body(body)
.post(result -> ResponseEntity.ok("success"));
}
}
</code>If you prefer a reactive stack, the same idea works with WebFlux. The controller below injects the target URI from configuration and forwards the request using ProxyExchange in a non‑blocking way.
<code>@RestController
@RequestMapping("/proxy/api")
public class GatewayController {
@Value("${remote.api}")
private URI api;
@GetMapping("")
public Mono<ResponseEntity<?>> proxy(ProxyExchange<Map<String, Object>> proxy) throws Exception {
return proxy.uri(api.toString() + "/creat/user").get();
}
}
</code>When you need to forward any path under a fixed prefix, you can use a wildcard mapping and let ProxyExchange forward the remaining part of the URI to the downstream service.
<code>@RestController
@RequestMapping("/proxy/api")
public class GatewayController {
@Value("${remote.api}")
private URI api;
@GetMapping("/**")
public Object common(ProxyExchange<Map<String, Object>> exchange) {
String path = exchange.path("/proxy/api/");
return exchange.uri(api.toString() + path).get();
}
}
</code>All gateway handler methods can leverage the full capabilities of Spring MVC and WebFlux, allowing you to inject request headers, query parameters, and apply annotations for request validation. The header() method on ProxyExchange lets you add or modify response headers, and you can provide a mapper function to transform the downstream ResponseEntity before returning it.
By default, sensitive headers such as Cookie and Authorization , as well as proxy‑related headers (e.g., x-forwarded-* ), are not forwarded to downstream services, enhancing security.
Done!!
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.