Real World Example

One Host for Every Client

Apps like Swiggy, Myntra and Paytm talk to one API host, while hundreds of services run behind it. Netflix built Zuul for this; Spring Cloud Gateway is the Spring successor. The ShopEase gateway setup:

Public pathRoute toAuthRate limit
GET /api/products/**product-servicepublic50/s per IP
/api/auth/**user-servicepublic5/s per IP (slows password guessing)
/api/cart/**, /api/users/**user-serviceJWT20/s per user
/api/orders/**order-serviceJWT2/s, burst 5 per user
/api/payments/**payment-serviceJWT2/s per user
/api/admin/**product / orderJWT + SCOPE_admin10/s

Fallback When a Service is Down

With the Resilience4j starter (spring-cloud-starter-circuitbreaker-reactor-resilience4j) the gateway can return a friendly response instead of a 500 when product-service is down:

spring:
  cloud:
    gateway:
      routes:
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/api/products/**
          filters:
            - name: CircuitBreaker
              args:
                name: productsCB
                fallbackUri: forward:/fallback/products
@RestController
class FallbackController {

    @GetMapping("/fallback/products")
    ResponseEntity<Map<String, Object>> productsFallback() {
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(Map.of(
                "message", "Products are taking longer than usual. Please try again in a minute.",
                "products", List.of()));
    }
}

Example

curl -i localhost:8080/api/products   # product-service stopped

Example output

HTTP/1.1 503 Service Unavailable
{"message":"Products are taking longer than usual. Please try again in a minute.","products":[]}

Tip: Put the gateway behind a cloud load balancer and run 2+ instances: it is now the most important single component of your system.