This episode covers microservices security and architecture: the API gateway pattern as a security boundary, Spring Cloud Gateway for routing and filtering, service-to-service authentication, and rate limiting and secure API contracts.

When an application grows into many small services, security is no longer just about a single application. Episode 14 discusses API gateway and secure microservices — how one secure entry point protects the entire system.
You'll understand the API gateway pattern as a security boundary, build a gateway with Spring Cloud Gateway, secure communication between services, and apply rate limiting and secure API contracts.
In a microservices architecture, each service must not be exposed directly to clients. The API gateway becomes a single entry point that routes requests to the right service. Its main benefits:
The gateway forms a trust boundary: the internal network only trusts requests that come through the gateway. Internal services must reject requests from outside. In a container environment, this rule is enforced with network policy.
Spring Cloud Gateway is built on WebFlux and provides reactive routing:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>This gateway is not an MVC application — it runs on the reactive Netty server. That's why routing is configured through YAML or a RouteLocator.
Define routes that connect public paths to internal services:
spring:
cloud:
gateway:
routes:
- id: item-service
uri: http://item-service:8080
predicates:
- Path=/api/items/**
- id: order-service
uri: http://order-service:8081
predicates:
- Path=/api/orders/**The predicate Path=/api/items/** ensures every request with the /api/items/ prefix is forwarded to item-service. With a gateway, clients call a single host — for example https://api.example.com — while internal routing is fully managed by the gateway.
Add filters to inject or modify headers before forwarding:
spring:
cloud:
gateway:
routes:
- id: item-service
uri: http://item-service:8080
predicates:
- Path=/api/items/**
filters:
- StripPrefix=1The StripPrefix=1 filter removes the first segment of the path — /api/items/123 becomes /items/123 on the service side. The combination of predicates and filters gives you full control over the request flow.
Two common patterns for service-to-service communication:
For the JWT pattern, the resource server configuration from episode 13 is applied in every service. An example service using client_credentials to call another service:
@Configuration
public class ServiceClientConfig {
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clients,
OAuth2AuthorizedClientService authorizedClients) {
return new AuthorizedClientServiceOAuth2AuthorizedClientManager(
clients, authorizedClients);
}
}This flow ensures every service proves its identity when calling another service — not just trusting requests from the internal network.
Even though the gateway validates tokens for external clients, internal services must still validate — don't rely on the assumption that requests always come from the gateway. This defense in depth principle protects services if there's a breach in the gateway.
Rate limiting protects the system from request spikes and abuse. Spring Cloud Gateway uses a bucket-based limiter; here's an example with Redis:
spring:
cloud:
gateway:
routes:
- id: item-service
uri: http://item-service:8080
predicates:
- Path=/api/items/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1The configuration above limits to an average of 10 requests per second with bursts up to 20. When the quota is exhausted, the gateway returns 429 Too Many Requests. Redis is used to track the counters in a distributed way.
Clear API contracts reduce miscommunication between teams. Recommended practices:
/api/v1/items — so changes don't break older clients.for i in $(seq 1 25); do
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/api/items
doneThe loop for i in $(seq 1 25); do curl ...; done sends 25 requests in a row. Notice that requests exceeding the limit receive 429 Too Many Requests — proof the rate limiter is working.
Episode 14 equipped you with microservices security and architecture: the API gateway pattern as a security boundary, routing and filtering with Spring Cloud Gateway, service-to-service authentication, and rate limiting and secure API contracts.
Key takeaways:
In the next episode, episode 15, we'll discuss reactive programming and WebFlux — the concepts of Mono and Flux, backpressure, building non-blocking applications with Spring WebFlux, reactive database integration with R2DBC, and a comparison with servlet-based applications.