Peter Penzov
Peter Penzov

Reputation: 1740

Configure Spring Gateway to forward web requests to internal url

I have Spring Gateway application with the following Gradle dependencies:

implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-gateway'
implementation 'com.netflix.eureka:eureka-core'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.boot:spring-boot-starter-actuator'

Route configuration:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder, LoggingGatewayFilterFactory loggingFactory) {

    return builder.routes()
            .route("service_route_clients_summary", r -> r.path("c")
                    .filters(f -> f.rewritePath("/api/management/home/clients/summary", "/management/home/clients/summary")
                            .filter(loggingFactory.apply(new LoggingGatewayFilterFactory.Config("My Custom Message", true, true))))
                    .uri("lb://merchant-hub-admin-service:8000/management/home/clients/summary"))
            .build();
}

I want to forward /api/management/home/clients/summary to internal link /management/home/clients/summary but using Eureka client to find the internal service.

When I rung the code nothing happened - path is not found. Any idea what can be wrong?

Upvotes: 0

Views: 2021

Answers (3)

Dhananjay
Dhananjay

Reputation: 1225

For Eureka discovery you could do something like this:

spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
          predicates:
            - name: Path
              args:
                pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
          filters:
            - name: RewritePath
              args:
                regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
                replacement: "'/${remaining}'"

Ofcourse you will need @EnableDiscoveryClient in your main class. If interested, could look into one of my test repos.

In eureka check /eureka/app and see metadata for your service. You will see if the service has a context path or not. If it does not, above configuration will work.

If the service do have a contextPath, you need to use folowwing in replacement key:

replacement: "{metadata.get('contextPath') != null ? metadata.get('contextPath') : ''} + '/${remaining}'"

Upvotes: 1

Vrubal
Vrubal

Reputation: 61

You can add filter expression which will trim the url as per your requirement.

Below config will make url as /api/management ==> /management

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

Upvotes: 3

DaveCat
DaveCat

Reputation: 813

Short version, the arguments you're passing into routes().route aren't correct.

You should try something like this:

    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p -> p.path(" /api/management/home/clients/summary **")
                        .filters(gatewayFilterSpec -> gatewayFilterSpec
                                .rewritePath("/management/home/clients/summary/(?<remaining>.*)"
                                , "/home/clients//${remaining}"))
                        .uri("lb:///home/clients/summary/"))
                .build();
    }

Upvotes: 1

Related Questions