Mastering Spring Cloud Gateway: Route Metadata, Timeouts, and Discovery Client

This guide explains how to configure route metadata in Spring Cloud Gateway 3.1.4, retrieve metadata via ServerWebExchange, set global and per‑route HTTP timeouts, use Java DSL for timeout settings, and enable DiscoveryClient‑based routing with custom predicates and filters.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring Cloud Gateway: Route Metadata, Timeouts, and Discovery Client

Route Metadata Configuration

You can use metadata to configure additional parameters for each route, for example:

spring:
  cloud:
    gateway:
      routes:
        - id: route_with_metadata
          uri: https://pack.com
          metadata:
            zone: "xj"
            infos:
              name: "value"
            weight: 0.2

All metadata attributes can be obtained from ServerWebExchange:

// Get the route object
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// Get route metadata
route.getMetadata();
// Get a specific metadata entry
route.getMetadata(someKey);

The exchange.getAttribute method stores the route object in the current context when the HandlerMapping looks up the route:

public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
  private final FilteringWebHandler webHandler;
  public RoutePredicateHandlerMapping(FilteringWebHandler webHandler, ...) {
    this.webHandler = webHandler;
    // ...
  }
  protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
    // Find route
    return lookupRoute(exchange)
      .flatMap(r -> {
        exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
        // Save the found route in the execution context
        exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
        return Mono.just(webHandler);
      }).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
        exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
      })));
  }
}

HTTP Timeout Configuration

HTTP timeouts (connection and response) can be configured globally and overridden per route.

Global timeout configuration

To configure global HTTP timeout, specify connection timeout in milliseconds and response timeout as a java.time.Duration:

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s

Per‑route timeout configuration

To configure timeout for an individual route, specify the values in the route’s metadata:

- id: per_route_timeouts
  uri: https://example.org
  predicates:
    - name: Path
      args:
        pattern: /delay/{timeout}
  metadata:
    response-timeout: 200
    connect-timeout: 200

Using the Java DSL you can set per‑route timeouts as follows:

import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder) {
  return routeBuilder.routes()
    .route("test1", r -> r.host("*.somehost.org")
      .and().path("/somepath")
      .filters(f -> f.addRequestHeader("header1", "header-value-1"))
      .uri("http://someuri")
      .metadata(RESPONSE_TIMEOUT_ATTR, 200)
      .metadata(CONNECT_TIMEOUT_ATTR, 200))
    .build();
}

Setting a negative timeout disables the global response timeout for that route:

- id: per_route_timeouts
  uri: https://example.org
  predicates:
    - name: Path
      args:
        pattern: /delay/{timeout}
  metadata:
    response-timeout: -1

Fluent Java routing API

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
  return builder.routes()
    .route(r -> r.host("**.abc.org").and().path("/image/png")
      .filters(f -> f.addResponseHeader("X-TestHeader", "foobar"))
      .uri("http://httpbin.org:80"))
    .route(r -> r.path("/image/webp")
      .filters(f -> f.addResponseHeader("X-AnotherHeader", "baz"))
      .uri("http://httpbin.org:80")
      .metadata("key", "value"))
    .route(r -> r.order(-1)
      .host("**.throttle.org").and().path("/get")
      .filters(f -> f.filter(throttle.apply(1,1,10,TimeUnit.SECONDS)))
      .uri("http://httpbin.org:80")
      .metadata("name", "pack"))
    .build();
}

This style also allows custom predicate assertions. RouteDefinitionLocator beans combine predicates with logical AND, and the fluent API supports and(), or(), and negate() on Predicate classes.

DiscoveryClient Route Definition Locator

You can configure the gateway to create routes based on services registered in a DiscoveryClient‑compatible registry. Enable it by setting spring.cloud.gateway.discovery.locator.enabled=true and ensure a DiscoveryClient implementation (Eureka, Consul, Zookeeper, Nacos) is on the classpath.

By default, routes created from DiscoveryClient use a path predicate defined as /serviceId/** where serviceId is the service name, and a rewrite‑path filter that strips the service ID before forwarding the request.

To customize predicates or filters, set spring.cloud.gateway.discovery.locator.predicates[x] and spring.cloud.gateway.discovery.locator.filters[y], preserving the default ones if needed. Example:

spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreaker
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"

End of guide.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring Cloud GatewayHTTP TimeoutDiscoveryClientJava DSLRoute Metadata
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

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.