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 onhttp://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 correspondingRID
(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();
}