Search code examples
javaspringspring-cloudspring-cloud-gateway

Spring Cloud Gateway - strip prefix if exists


I need Spring Cloud Gateway to route a request to the microservice based on either Host header or a path prefix. In any case the path prefix must be removed from the path, but only if it's set.

I've came up with the following code where I consider only "sip" to be a prefix:

public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.host("sip")
                        .or()
                        .path("/sip/**")
                        .filters(f -> f.stripPrefix(1))
                        .uri("http://sip:8080")
                )
                .build();
}

The problem is that Spring removes the first segment of the path even if it's not a prefix.

For example, a request with the path /sip/calls succeeds, but /calls with the Host header set doesn't, because Spring considers /calls a prefix and removes it which results in the empty path. /calls/calls path with the Host header succeeds because Spring removes only the first calls path segment.

How can I use host and path together, removing the prefix only if it matches to the defined value?

ps I was thinking about two routes per service but it doesn't look good, though it achieves the goal:

.route(r -> r.header("Host", "form").uri("http://form:8080"))
                .route(r -> r.path("/form/**")
                        .filters(f -> f.stripPrefix(1))
                        .uri("http://form:8080"))

Solution

  • you can do like this

    .route(r -> r.host("sip")
                .or()
                .path("/sip/**")
                .filters(f -> f.rewritePath("^/sip", ""))
                .uri("http://sip:8080")