super.t
super.t

Reputation: 2746

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"))

Upvotes: 5

Views: 14588

Answers (2)

justCurious
justCurious

Reputation: 957

The removal behavior is normal, you can use another route for /calls and for that route, you don't add remove prefix clause.

Official doc: https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-stripprefix-gatewayfilter-factory

Upvotes: 0

Jason Yu
Jason Yu

Reputation: 98

you can do like this

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

Upvotes: 7

Related Questions