Backend Development 24 min read

Spring Cloud Gateway: Service Gateway Basics, Deployment, Routing, Filters, Nacos Integration, Apollo Dynamic Configuration, and Global Exception Handling

This comprehensive guide explains why a service gateway is needed in microservice architectures, details Spring Cloud Gateway's core concepts, deployment steps, route and predicate configurations, local and global filters, integration with Nacos for service discovery, dynamic routing via Apollo, and custom global exception handling, providing code examples throughout.

Top Architect
Top Architect
Top Architect
Spring Cloud Gateway: Service Gateway Basics, Deployment, Routing, Filters, Nacos Integration, Apollo Dynamic Configuration, and Global Exception Handling

1. Why a Service Gateway Is Needed

In microservice architectures, a gateway acts as the single entry point, simplifying client interactions, reducing coupling, and centralizing cross‑cutting concerns such as routing, load balancing, and security.

2. Basic Functions of a Service Gateway

Simplifies client calls by exposing a unified API.

Reduces coupling between services.

Handles non‑business functions like authentication, rate limiting, and circuit breaking.

3. Deploying a Service Gateway

3.1 Dependency Declaration

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-gateway</artifactId>
 </dependency>

3.2 Adding the Dependency

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-gateway</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </exclusion>
  </exclusions>
</dependency>

3.3 Configuring Application Name and Port

server:
  port: 9023
  servlet:
    context-path: ${spring.application.name}
spring:
  application:
    name: gateway

4. Spring Cloud Gateway Configuration

4.1 Route Definition

spring:
  cloud:
    gateway:
      routes:
        - id: gateway-provider_1
          uri: http://localhost:9024
          predicates:
            - Path=/gateway/provider/**
          filters:
            - StripPrefix=1
            - AddResponseHeader=X-Response-Foo,Bar

4.2 Predicate (RoutePredicateFactory)

Predicates match request attributes; common ones include Path , Method , and Weight . They are defined under predicates in the route.

4.3 Filter (GatewayFilterFactory)

Filters can be pre (executed before routing) or post (after routing). Examples include StripPrefix and AddResponseHeader . Custom filters are created by extending AbstractGatewayFilterFactory and registering with @Component .

Custom Local Filter Example

@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config> {
    // implementation omitted for brevity
}

Custom Global Filter Example

@Component
@Order(Integer.MIN_VALUE)
public class AccessLogGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // pre‑processing
        return chain.filter(exchange)
            .then(Mono.fromRunnable(() -> {
                // post‑processing, e.g., logging
            }));
    }
}

5. Integrating Nacos for Service Discovery

By adding spring-cloud-starter-alibaba-nacos-discovery and enabling @EnableDiscoveryClient , routes can use lb://service-name to obtain instances from Nacos and achieve load balancing.

spring:
  cloud:
    gateway:
      routes:
        - id: gateway-provider_1
          uri: lb://gateway-provider
          predicates:
            - Path=/gateway/provider/**

6. Dynamic Routing with Apollo

Adding the Apollo client dependency and a configuration change listener allows routes to be refreshed without restarting the gateway.

@ApolloConfigChangeListener(interestedKeyPrefixes = "spring.cloud.gateway.")
public void onChange(ConfigChangeEvent changeEvent) {
    // refresh gateway properties and routes
}

6.1 Exposing Management Endpoints

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

7. Custom Global Exception Handler

Implement ErrorWebExceptionHandler to return JSON error responses instead of the default HTML error page.

@Component
@Order(-1)
public class GlobalErrorExceptionHandler implements ErrorWebExceptionHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        // build JSON error body
        return response.writeWith(Mono.fromSupplier(() -> {
            byte[] bytes = objectMapper.writeValueAsBytes(new CommonResponse("500", ex.getMessage(), null));
            return response.bufferFactory().wrap(bytes);
        }));
    }
}

Conclusion

The article demonstrates how to build a robust Spring Cloud Gateway with routing, filters, service discovery via Nacos, dynamic configuration via Apollo, and graceful error handling, providing a solid foundation for microservice gateway development.

JavaMicroservicesBackend DevelopmentNacosDynamic RoutingSpring Cloud GatewayApolloservice gateway
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.