6
votes

How to forward a path variable in Spring Cloud Gateway 2.0?

If we have an microservice that has 2 endpoints: /users and /users/{id} and is running on port 8080, how to forward the request to the endpoint with the id path variable?

The following gateway configuration successfully forwards to the /users end point, but the second route forwards the request to the same /users endpoint of the real service.

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("users", t -> t.path("/users").uri("http://localhost:8080/users"))
        .route("userById", t -> t.path("/users/**").uri("http://localhost:8080/users/"))
        .build();
}

I'm using spring-cloud-starter-gateway from spring cloud Finchley.BUILD-SNAPSHOT

2

2 Answers

10
votes

A rewritePath filter has to be used:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("users", t -> t.path("/users")
                .uri("http://localhost:8080/users"))
            .route("userById", t -> t.path("/users/**")
                .filters(rw -> rw.rewritePath("/users/(?<segment>.*)", "/users/${segment}"))
                .uri("http://localhost:8080/users/"))
        .build();
    }

The YAML version is specified in the documentation:

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

After some research, please find below what worked for me. Both methods produce the same result.

Here is my 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();
}