Spring Cloud Gateway - Proxy/Forward the entire sub part of URL

We were running a similar issue here, and although I agree with Boyen's response, it may be useful to point out that the "uri" parameter ignores the "path" component of the URI. This is not clear in the documentation (or I haven't found it at least), so I hope it helps others.

Suppose you want to redirect all the requests received at /foo to http://example.org/bar

For example: /foo/x/y/z --> http://example.org/bar/x/y/z

For instance this WORKS AS EXPECTED:

spring:   
  cloud:
     gateway:
       routes:
       - id: rewritepath_route
         uri: http://example.org
         predicates:
         - Path=/foo/**
         filters:
         - RewritePath=/foo/(?<segment>.*), /bar/$\{segment}

While this DOES NOT WORK as expected (it ignores /bar):

spring:   
  cloud:
     gateway:
       routes:
       - id: rewritepath_route
         uri: http://example.org/bar
         predicates:
         - Path=/foo/**
         filters:
         - RewritePath=/foo/(?<segment>.*), /$\{segment}

Please find below the two types of configuration with a full set-up. Both methods produce the same result.

Set-up:

  • the gateway is running on http://localhost:8090
  • a base path called /context serves as the entry point of the gateway
  • a service called my-resources running on http://localhost:8091/my-resources. When /my-resources is invoked without parameters, it returns all resources. When it is invoked with a parameters it returns the resource with the corresponding RID (if any)

The gateway is configured so that all path variables (possibly none) transmitted to http://localhost:8090/context/my-resources/ is forwarded to uri http://localhost:8091/my-resources/.

Method 1: using application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: route_id
        predicates:
        - Path=/context/my-resources/**
        filters:
        - RewritePath=/context/my-resources/(?<RID>.*), /my-resources/$\{RID}
        uri: http://localhost:8091

Method 2: using Java like configuration

@Bean
public RouteLocator routes(RouteLocatorBuilder routeBuilder) {
    return routeBuilder.routes()
            .route("route_id",
                    route -> route
                            .path("/context/my-resources/**")
                            .filters(f -> f.rewritePath("/context/my-resources/(?<RID>.*)", "/my-resources/${RID}"))
                            .uri("http://localhost:8091")
            )
            .build();
}

You can use the rewritePath functionality in your path filters, as specified by the documentation found here :

https://cloud.spring.io/spring-cloud-gateway/reference/html/#rewritepath-gatewayfilter-factory

Relevant parts :

5.12 RewritePath GatewayFilter Factory

The RewritePath GatewayFilter Factory takes a path regexp parameter and a replacement parameter. This uses Java regular expressions for a flexible way to rewrite the request path.

spring:   
  cloud:
     gateway:
       routes:
       - id: rewritepath_route
         uri: http://example.org
         predicates:
         - Path=/foo/**
         filters:
         - RewritePath=/foo/(?<segment>.*), /$\{segment}

For a request path of /foo/bar, this will set the path to /bar before making the downstream request. Notice the $\ which is replaced with $ because of the YAML spec.

In your example, that would look like :

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
    String test = "http://localhost:4178";

    return builder.routes()
            .route("integration-test", r -> r
                    .path("/integration/sbl/**")
                    .filters(f->f.rewritePath("/integration/(?<segment>.*)","/a-integration/${segment}"))
                    .uri(test)
                  )
            .build();
}